@openclaw/codex 2026.9.5 → 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 (174) hide show
  1. package/README.md +2 -0
  2. package/assets/icon.png +0 -0
  3. package/dist/.setup/{account-usage-runtime-C2MOIvfq.mjs → account-usage-runtime-DFhbh1zz.mjs} +6 -6
  4. package/dist/.setup/{apply-CJ0ZfmBG.mjs → apply-D3GcSoSa.mjs} +35 -55
  5. package/dist/.setup/{attempt-client-cleanup-BpYKdTA0.mjs → attempt-client-cleanup-DOP-cW5j.mjs} +179 -73
  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-QirmgiCo.mjs → auth-cache-key-Dbvq-QgB.mjs} +41 -111
  9. package/dist/.setup/{auth-profile-WqZtZfXN.mjs → auth-profile-B0okYl2D.mjs} +1 -2
  10. package/dist/.setup/auth-profile-health-oHizqgye.mjs +53 -0
  11. package/dist/.setup/auth-profile-recovery-BREezV0L.mjs +14 -0
  12. package/dist/.setup/auth-start-options-BPIPeEX8.mjs +44 -0
  13. package/dist/.setup/{binding-connection-Bm38niE8.mjs → binding-connection-DTtN1KrX.mjs} +2 -2
  14. package/dist/.setup/{binding-connection.runtime-CnRMC0ta.mjs → binding-connection.runtime-6TpgD1M6.mjs} +5 -5
  15. package/dist/.setup/{bounded-turn-BtlZcivC.mjs → bounded-turn-CbjoN2OW.mjs} +140 -37
  16. package/dist/.setup/bounded-turn-isolation-B8K_ylqk.mjs +14 -0
  17. package/dist/.setup/{build-state-Xx9ybZqa.mjs → build-state-Da1_z0kd.mjs} +1 -1
  18. package/dist/.setup/{capabilities-_vXcZGSx.mjs → capabilities-B3WEZl4e.mjs} +2 -10
  19. package/dist/.setup/{client-vXs2929Q.mjs → client-N0JpgSzF.mjs} +635 -872
  20. package/dist/.setup/client-catalog-response-5HHLdcde.mjs +285 -0
  21. package/dist/.setup/{command-dispatch-naHIZwwF.mjs → command-dispatch-BeAoaovI.mjs} +9 -8
  22. package/dist/.setup/{command-formatters-CGEkdawF.mjs → command-formatters-R3ckE3Co.mjs} +36 -64
  23. package/dist/.setup/{command-handlers-BtAJEW1X.mjs → command-handlers-ylTMS00z.mjs} +301 -488
  24. package/dist/.setup/{command-rpc-DHFpn4le.mjs → command-rpc-CGJGUQ6Y.mjs} +40 -28
  25. package/dist/.setup/compact-C2WamavS.mjs +776 -0
  26. package/dist/.setup/{config-CedDWjM-.mjs → config-DKhXquav.mjs} +26 -28
  27. package/dist/.setup/{config-options-BsanJ8QG.mjs → config-options-CzyWLTJt.mjs} +68 -65
  28. package/dist/.setup/{config-parsing-CcB9iPoq.mjs → config-parsing-b088LyhT.mjs} +57 -60
  29. package/dist/.setup/{config-runtime-CeAhl_h4.mjs → config-runtime-C0NbLms1.mjs} +2 -2
  30. package/dist/.setup/{config-security-BRQ2mgW9.mjs → config-security-CE-FcGw9.mjs} +51 -215
  31. package/dist/.setup/{config-utils-DujwEnhg.mjs → config-utils-D0CXecki.mjs} +3 -13
  32. package/dist/.setup/context-engine-projection-PezSESth.mjs +387 -0
  33. package/dist/.setup/{conversation-binding-DhzrpTM6.mjs → conversation-binding-3Min8qvP.mjs} +71 -105
  34. package/dist/.setup/{conversation-binding-data-CrcyZk6O.mjs → conversation-binding-data-C746z5Pn.mjs} +8 -12
  35. package/dist/.setup/{conversation-control-DN53ns41.mjs → conversation-control-CEP8X5JC.mjs} +30 -69
  36. package/dist/.setup/{cyber-failover-DYwbmf1o.mjs → cyber-failover-XV0nNRZu.mjs} +1 -1
  37. package/dist/.setup/{cyber-failover-notice-e9G3J9-e.mjs → cyber-failover-notice-RNpGpTyP.mjs} +1 -1
  38. package/dist/.setup/{dynamic-tools-D16lOp67.mjs → dynamic-tools-DzlsLUuS.mjs} +3136 -3167
  39. package/dist/.setup/{effective-mcp-catalog-K6kLCN8X.mjs → effective-mcp-catalog-CxUtC-xG.mjs} +8 -17
  40. package/dist/.setup/{ephemeral-turn-R1gA8Sn6.mjs → ephemeral-turn-CDsPJOa2.mjs} +9 -6
  41. package/dist/.setup/event-projector-assistant-message-CigreO4K.mjs +69 -0
  42. package/dist/.setup/{event-projector-usage-C7Ntzs-f.mjs → event-projector-usage-03R0I2dM.mjs} +4 -26
  43. package/dist/.setup/event-projector-values-DJSz8BTk.mjs +106 -0
  44. package/dist/.setup/incognito-session-DWYapfwf.mjs +2 -0
  45. package/dist/.setup/{inference-context-fulhZuz8.mjs → inference-context-D-9gWlTR.mjs} +16 -18
  46. package/dist/.setup/inference-dispatch-CMZtjQyz.mjs +359 -0
  47. package/dist/.setup/inference-metadata-CgIf7sOx.mjs +81 -0
  48. package/dist/.setup/inference-proxy-DhcXOgUE.mjs +561 -0
  49. package/dist/.setup/{isolated-completion-B6srt48J.mjs → isolated-completion-Dm3PzxJk.mjs} +15 -11
  50. package/dist/.setup/launch-args-DbFCehO7.mjs +196 -0
  51. package/dist/.setup/{managed-binary-DP6Rib3P.mjs → managed-binary-kiWRhNRE.mjs} +16 -9
  52. package/dist/.setup/{model-catalog-DkvUuBey.mjs → model-catalog-PAuZgJC6.mjs} +14 -14
  53. package/dist/.setup/model-runtime-BdqzOMkU.mjs +11 -0
  54. package/dist/.setup/{models-BDFgm_G-.mjs → models-DHXZtVVk.mjs} +9 -18
  55. package/dist/.setup/{native-auth-BLZGqFjw.mjs → native-auth-CuG53tu4.mjs} +5 -5
  56. package/dist/.setup/{native-execution-policy-YBMHSzC4.mjs → native-execution-policy-BxZJy5mP.mjs} +6 -31
  57. package/dist/.setup/{native-subagent-monitor-B1hxzIOy.mjs → native-subagent-monitor-Dpsmf2wz.mjs} +4422 -3808
  58. package/dist/.setup/native-subagent-pending-assignments-DwkCzLvD.mjs +203 -0
  59. package/dist/.setup/native-task-assignments-DMQ0g3hu.mjs +194 -0
  60. package/dist/.setup/{node-cli-sessions-Cl8b2ZF3.mjs → node-cli-sessions-HC4W6FLI.mjs} +99 -111
  61. package/dist/.setup/node-exec-server.runtime-BgBfWQqo.mjs +244 -0
  62. package/dist/.setup/{plan-xD7WKYTM.mjs → plan-Y-QIvrKB.mjs} +118 -163
  63. package/dist/.setup/{plugin-activation-r8nq5Jzp.mjs → plugin-activation-cNHRfaxU.mjs} +10 -47
  64. package/dist/.setup/{plugin-app-cache-key-BOxKP7db.mjs → plugin-app-cache-key-BL9B5H0L.mjs} +9 -42
  65. package/dist/.setup/{plugin-inventory-DUle8DLz.mjs → plugin-inventory-Cky2XJUw.mjs} +32 -23
  66. package/dist/.setup/{plugin-marketplace-discovery-P-Vndfqq.mjs → plugin-marketplace-discovery-D_dV9FXa.mjs} +22 -25
  67. package/dist/.setup/{plugin-metadata-cache-DsS5buNa.mjs → plugin-metadata-cache-DsjsL1dr.mjs} +328 -318
  68. package/dist/.setup/protocol-CANUwXJ3.mjs +17 -0
  69. package/dist/.setup/provider-DH8NSzGt.mjs +51 -0
  70. package/dist/.setup/{provider-capabilities-B8J4Dy-O.mjs → provider-capabilities-CAxoF-X1.mjs} +35 -12
  71. package/dist/.setup/{rate-limits-DOEGYRNs.mjs → rate-limits-B7-X2TgG.mjs} +123 -166
  72. package/dist/.setup/{request-BioXJLYa.mjs → request-BHZ1nz8d.mjs} +25 -16
  73. package/dist/.setup/responses-oauth-twnuTaAa.mjs +93 -0
  74. package/dist/.setup/rpc-error-BlD2vuzn.mjs +31 -0
  75. package/dist/.setup/{run-attempt-rlA07pUv.mjs → run-attempt-D8RZUOzY.mjs} +2046 -1454
  76. package/dist/.setup/{run-attempt-lifecycle-B7JbY4-F.mjs → run-attempt-lifecycle-C-6O3Exn.mjs} +10 -24
  77. package/dist/.setup/{runtime-artifact-Dy38Z5iU.mjs → runtime-artifact-DDQ-HGXf.mjs} +43 -47
  78. package/dist/.setup/runtime-artifact-connection-D68qQn1m.mjs +78 -0
  79. package/dist/.setup/sandbox-guard-DjCz2eOw.mjs +126 -0
  80. package/dist/.setup/scope-DOC1Xjc8.mjs +6 -0
  81. package/dist/.setup/session-binding-DGCYAfvD.mjs +443 -0
  82. package/dist/.setup/{session-binding-record-TH3xA0zj.mjs → session-binding-record-Oe9L-CNY.mjs} +73 -132
  83. package/dist/.setup/{session-binding-sidecars-CKYEcfNn.mjs → session-binding-sidecars-jo6H8dFr.mjs} +242 -60
  84. package/dist/.setup/{session-catalog-fUdWDx-U.mjs → session-catalog-4sCdv5qx.mjs} +598 -452
  85. package/dist/.setup/{session-catalog-adoption-CR_whkEW.mjs → session-catalog-adoption-BU_pHWG7.mjs} +59 -26
  86. package/dist/.setup/{session-catalog-archive-CwZaPacf.mjs → session-catalog-archive-spHfihri.mjs} +7 -7
  87. package/dist/.setup/session-catalog-events-DePDzzjc.mjs +139 -0
  88. package/dist/.setup/session-catalog-home-id-vlih0B_g.mjs +22 -0
  89. package/dist/.setup/{session-catalog-index-B141u15s.mjs → session-catalog-index-CZvDzC6z.mjs} +286 -182
  90. package/dist/.setup/{session-catalog-index-order-Cc5BzlQr.mjs → session-catalog-index-order-BcQpHks3.mjs} +2 -2
  91. package/dist/.setup/{session-catalog-index-state-BAuDztHN.mjs → session-catalog-index-state-TeO7EyO-.mjs} +6 -2
  92. package/dist/.setup/session-catalog-limits-DDxOsQeC.mjs +14 -0
  93. package/dist/.setup/session-catalog-list-request-CvtxrYSe.mjs +170 -0
  94. package/dist/.setup/session-catalog-native-projection-DjhwGL6x.mjs +178 -0
  95. package/dist/.setup/{session-catalog-node-adoption-BVRsYOSh.mjs → session-catalog-node-adoption-DgXvSGu0.mjs} +30 -35
  96. package/dist/.setup/{session-catalog-node-continue-Dowv8osw.mjs → session-catalog-node-continue-DjKXHBbi.mjs} +25 -18
  97. package/dist/.setup/session-catalog-node-lookup-CtAXI5W5.mjs +56 -0
  98. package/dist/.setup/{session-catalog-native-projection-ChV3cCtm.mjs → session-catalog-parsing-CPGaPYr-.mjs} +14 -180
  99. package/dist/.setup/{session-catalog-projection-C1Bj9Jl-.mjs → session-catalog-projection-Cr5qP5Dj.mjs} +15 -5
  100. package/dist/.setup/session-catalog-provenance-DoAvktcj.mjs +95 -0
  101. package/dist/.setup/{session-cli-DIj-IE-E.mjs → session-cli-Cn_nCqfq.mjs} +11 -24
  102. package/dist/.setup/{session-history-C--SrLI8.mjs → session-history-D83lJWHG.mjs} +16 -23
  103. package/dist/.setup/{session-history-import-JHXT5Xfi.mjs → session-history-import-WhX-X33a.mjs} +7 -10
  104. package/dist/.setup/session-history-read-Ov3StuL4.mjs +133 -0
  105. package/dist/.setup/{session-history.worker-CpNj7H_P.mjs → session-history.worker-MnPKncqP.mjs} +14 -23
  106. package/dist/.setup/session-initialization-6aveB9qb.mjs +22 -0
  107. package/dist/.setup/{session-permission-policy-DhurXY0l.mjs → session-permission-policy-Ci_fVX6y.mjs} +4 -8
  108. package/dist/.setup/{session-retirement-CU87AOg9.mjs → session-retirement-qMTxkNx2.mjs} +31 -12
  109. package/dist/.setup/{settled-turn-context-fmwouT5I.mjs → settled-turn-context-D4yj4rxf.mjs} +1 -1
  110. package/dist/.setup/{settled-turn-finalizer-CiY2bLFK.mjs → settled-turn-finalizer-BsvEabkw.mjs} +17 -13
  111. package/dist/.setup/{shared-client-BpTtuLQ5.mjs → shared-client-DqyTMYug.mjs} +826 -485
  112. package/dist/.setup/shared-client-lifecycle-DJIgqgMw.mjs +153 -0
  113. package/dist/.setup/{side-question-DSCZyoBD.mjs → side-question-C4kCmQy1.mjs} +206 -334
  114. package/dist/.setup/{source-Bjp4UQij.mjs → source-CS_7GFJZ.mjs} +82 -139
  115. package/dist/.setup/spawn-error-CL3n6MAa.mjs +57 -0
  116. package/dist/.setup/{thread-archive-guard-jmecf6OJ.mjs → thread-archive-guard-C9frICzX.mjs} +10 -3
  117. package/dist/.setup/thread-lifecycle-DPflntEJ.mjs +2362 -0
  118. package/dist/.setup/{incognito-session-uhrBF6wJ.mjs → thread-ownership-queue-Dp24d7-F.mjs} +1 -2
  119. package/dist/.setup/{thread-ownership-skomxnIt.mjs → thread-ownership-roNP0l1c.mjs} +47 -10
  120. package/dist/.setup/thread-policy-DTd-DtkX.mjs +109 -0
  121. package/dist/.setup/thread-requests-B_bRnMGN.mjs +2102 -0
  122. package/dist/.setup/{thread-resume-BkNpj9Pz.mjs → thread-resume-CdDaoc7T.mjs} +6 -6
  123. package/dist/.setup/timeout-CXOfNoaX.mjs +46 -0
  124. package/dist/.setup/transcript-history-projection-DRSifI-1.mjs +201 -0
  125. package/dist/.setup/{transcript-mirror-attestation-CzM-94NC.mjs → transcript-mirror-attestation-YSegaktH.mjs} +3 -4
  126. package/dist/.setup/{transcript-mirror-D4qp_leP.mjs → transcript-mirror-kxmCYsuF.mjs} +224 -206
  127. package/dist/.setup/{transport-stdio-Cmx94Oiy.mjs → transport-stdio-Bdegpn2V.mjs} +138 -75
  128. package/dist/.setup/transport-websocket-BTBE-LD9.mjs +211 -0
  129. package/dist/.setup/{upstream-prompt-provenance-LphB8slG.mjs → upstream-prompt-provenance-fXkKbPVC.mjs} +3 -9
  130. package/dist/.setup/{upstream-session-fork-D3UKxgVD.mjs → upstream-session-fork-CBeVjBpT.mjs} +48 -40
  131. package/dist/.setup/{usage-BOgBEKso.mjs → usage-BMzNxeR_.mjs} +5 -4
  132. package/dist/.setup/{usage-limit-error-C0ow7DOc.mjs → usage-limit-error-QXerDo3i.mjs} +5 -20
  133. package/dist/.setup/{web-search-provider.runtime-CTGuJt6i.mjs → web-search-provider.runtime-P77OUeoo.mjs} +10 -20
  134. package/dist/api.js +25 -16
  135. package/dist/catalog-page-worker-entrypoint.js +12 -0
  136. package/dist/catalog-page.worker.js +9 -0
  137. package/dist/cli-metadata.js +1 -1
  138. package/dist/doctor-contract-api.js +50 -8
  139. package/dist/harness.js +344 -1
  140. package/dist/index.js +345 -346
  141. package/dist/media-understanding-provider.js +9 -22
  142. package/dist/migration-provider-api.js +1 -1
  143. package/dist/provider-discovery.js +1 -1
  144. package/dist/session-history-worker-runtime.js +16 -33
  145. package/dist/session-history.worker.js +1 -1
  146. package/openclaw.plugin.json +14 -2
  147. package/package.json +11 -7
  148. package/dist/.setup/attempt-context-VXVwTCfS.mjs +0 -636
  149. package/dist/.setup/compact-C3i3qlzj.mjs +0 -687
  150. package/dist/.setup/event-projector-assistant-message-DNUR1s0A.mjs +0 -105
  151. package/dist/.setup/event-projector-items-DyTQ_XqL.mjs +0 -200
  152. package/dist/.setup/harness-rxaaoN-o.mjs +0 -349
  153. package/dist/.setup/history-rejection-B4nOXNXF.mjs +0 -13
  154. package/dist/.setup/image-payload-sanitizer-tupAr-2o.mjs +0 -79
  155. package/dist/.setup/inference-proxy-CC15HuSi.mjs +0 -311
  156. package/dist/.setup/launch-args-DnMak49W.mjs +0 -111
  157. package/dist/.setup/local-runtime-attribution-B_2mnqhb.mjs +0 -19
  158. package/dist/.setup/native-subagent-history-YXaL6dMd.mjs +0 -135
  159. package/dist/.setup/native-subagent-task-ids-DsuOonKv.mjs +0 -411
  160. package/dist/.setup/node-exec-server.runtime-BaViBKNz.mjs +0 -226
  161. package/dist/.setup/plugin-approval-roundtrip-CjfzafAZ.mjs +0 -122
  162. package/dist/.setup/provider-fFh_-VR3.mjs +0 -50
  163. package/dist/.setup/rolldown-runtime-8H4AJuhK.mjs +0 -14
  164. package/dist/.setup/sandbox-guard-BBP-RbTf.mjs +0 -166
  165. package/dist/.setup/session-binding-_0W_fHRr.mjs +0 -721
  166. package/dist/.setup/session-catalog-events-jMcYfQyd.mjs +0 -250
  167. package/dist/.setup/session-history-read-B3ZfSUbF.mjs +0 -50
  168. package/dist/.setup/session-initialization-DH1z6fXn.mjs +0 -75
  169. package/dist/.setup/thread-history-page-BTx-4xsg.mjs +0 -83
  170. package/dist/.setup/thread-lifecycle-Cik28qWn.mjs +0 -4904
  171. package/dist/.setup/thread-policy-Cjs4B8xf.mjs +0 -54
  172. package/dist/.setup/timeout-DZF05XrR.mjs +0 -63
  173. package/dist/.setup/transcript-history-projection-DHNBDhCU.mjs +0 -243
  174. package/dist/.setup/version-CoqzXPgK.mjs +0 -12
@@ -1,39 +1,236 @@
1
- import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
- import { _ as resolveCodexAppServerUserHomeDir, m as isJsonObject } from "./config-security-BRQ2mgW9.mjs";
3
- import { a as closeCodexCatalogClientSource, l as recordCodexCatalogResponseSource, n as projectCodexCatalogNativeResponse, o as codexCatalogSourceForClient } from "./session-catalog-native-projection-ChV3cCtm.mjs";
4
- import { r as MIN_SUPPORTED_CODEX_APP_SERVER_VERSION, t as CODEX_APP_SERVER_VERSION } from "./version-CoqzXPgK.mjs";
5
- import { a as hasCodexAppServerNaturalExit, i as closeCodexAppServerTransportAndWait, r as closeCodexAppServerTransport, t as createStdioTransport } from "./transport-stdio-Cmx94Oiy.mjs";
6
- import { i as CodexAppServerRpcError, r as CODEX_APP_SERVER_OVERLOADED_ERROR_CODE } from "./timeout-DZF05XrR.mjs";
7
- import "./config-CedDWjM-.mjs";
8
- import { n as resolveCodexAppServerRuntimeOptions } from "./config-runtime-CeAhl_h4.mjs";
1
+ import { a as stringifyCodexAppServerMessage, c as isRpcResponse, i as readCodexCatalogDecodeRoute, n as projectCodexCatalogMessage, o as CodexAppServerMessageDecoder, r as listenCodexAppServerLines, s as redactCodexAppServerLinePreview } from "./client-catalog-response-5HHLdcde.mjs";
2
+ import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
3
+ import { c as MIN_SUPPORTED_CODEX_APP_SERVER_VERSION, s as CODEX_APP_SERVER_VERSION } from "./managed-binary-kiWRhNRE.mjs";
4
+ import { a as closeCodexAppServerTransportAndWait, i as closeCodexAppServerTransport, o as hasCodexAppServerNaturalExit, t as createStdioTransport } from "./transport-stdio-Bdegpn2V.mjs";
5
+ import { n as CodexAppServerRpcError, t as CODEX_APP_SERVER_OVERLOADED_ERROR_CODE } from "./rpc-error-BlD2vuzn.mjs";
6
+ import { f as recordCodexCatalogResponseSource, i as reuseCodexCatalogPreview, o as closeCodexCatalogClientSource, s as codexCatalogSourceForClient } from "./session-catalog-native-projection-DjhwGL6x.mjs";
7
+ import { n as resolveCodexAppServerRuntimeOptions } from "./config-runtime-C0NbLms1.mjs";
8
+ import { codexCatalogPageWorkerEntrypoint } from "../catalog-page-worker-entrypoint.js";
9
+ import { t as createWebSocketTransport } from "./transport-websocket-BTBE-LD9.mjs";
10
+ import { t as __exportAll } from "./session-binding-sidecars-jo6H8dFr.mjs";
9
11
  import { isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
10
12
  import { randomUUID } from "node:crypto";
11
- import { addSafeTimeoutDelayGraceMs, addTimerTimeoutGraceMs, parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
12
13
  import { normalizeJsonSchemaForTypeBox } from "openclaw/plugin-sdk/json-schema-runtime";
14
+ import { addSafeTimeoutDelayGraceMs, addTimerTimeoutGraceMs, parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
13
15
  import path from "node:path";
14
- import { EventEmitter } from "node:events";
15
16
  import { coerceErrorMessage, toStringifiedError } from "openclaw/plugin-sdk/error-runtime";
16
17
  import { sliceUtf16Safe, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
18
+ import { AsyncLocalStorage } from "node:async_hooks";
17
19
  import { hasPendingInternalDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime";
18
20
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
19
21
  import { OPENCLAW_VERSION, embeddedAgentLog, formatToolExecutionErrorMessage, normalizeQuestionTimeoutSeconds, resolveToolExecutionErrorKind } from "openclaw/plugin-sdk/agent-harness-runtime";
20
- import { createInterface } from "node:readline";
21
22
  import { parse } from "semver";
22
- import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
23
- import { copyInternalToolResultState } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
23
+ import { AsyncWorkScope } from "openclaw/plugin-sdk/concurrency-runtime";
24
+ import { copyInternalToolResultState, runWithAsyncWorkResources } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
24
25
  import { Compile } from "typebox/compile";
25
- import net from "node:net";
26
- import { PassThrough, Writable } from "node:stream";
27
- import { StringDecoder } from "node:string_decoder";
28
- import { WebSocket } from "openclaw/plugin-sdk/websocket-runtime";
29
- //#region extensions/codex/src/app-server/protocol-json.ts
30
- function isRpcResponse(message) {
31
- return "id" in message && !("method" in message);
26
+ //#region extensions/codex/src/app-server/client-catalog-worker.ts
27
+ const INLINE_CATALOG_MAX_BYTES = 65536;
28
+ const CATALOG_WORKER_IDLE_MS = 6e4;
29
+ const runInCatalogWorkerContext = AsyncLocalStorage.snapshot();
30
+ /** Late responses retain their decode route after cancellation removes the waiter. */
31
+ function codexCatalogRequestId(method, params, sequence, catalogPreview) {
32
+ const kind = catalogPreview ? method === "thread/list" ? "list" : method === "thread/read" && isJsonObject(params) && params.includeTurns !== true ? "thread" : void 0 : void 0;
33
+ return kind ? Number.MAX_SAFE_INTEGER - 2 * sequence - (kind === "thread" ? 1 : 0) : sequence;
34
+ }
35
+ /** Each physical client owns one decoder, including incomplete-line recovery state. */
36
+ var CodexCatalogWorker = class {
37
+ constructor() {
38
+ this.setTimeoutFn = setTimeout;
39
+ this.clearTimeoutFn = clearTimeout;
40
+ this.closed = false;
41
+ }
42
+ get continuation() {
43
+ return this.continuationRoute;
44
+ }
45
+ async decode(line, route, attempts, projections) {
46
+ if (this.closed) return;
47
+ if (!this.continuationRoute && route !== "unresolved" && line.byteLength <= INLINE_CATALOG_MAX_BYTES) {
48
+ let parsed;
49
+ try {
50
+ parsed = JSON.parse(line.toString("utf8"));
51
+ } catch {}
52
+ if (parsed !== void 0) {
53
+ await Promise.resolve();
54
+ if (this.closed) return;
55
+ const attempt = attempts.get(route.id);
56
+ const projection = attempt ? projections.get(attempt) : void 0;
57
+ return projectCodexCatalogMessage(parsed, {
58
+ route,
59
+ remainingRows: attempt ? projection?.remainingRows : 0
60
+ }, projection?.preview);
61
+ }
62
+ }
63
+ this.clearTimeoutFn(this.idleTimer);
64
+ this.idleTimer = void 0;
65
+ await this.retirement;
66
+ if (this.closed) return;
67
+ if (!this.pool) {
68
+ const { resolveRuntimeWorkerUrl, WorkerTaskPool } = await import("openclaw/plugin-sdk/process-runtime");
69
+ if (this.closed) return;
70
+ this.pool = new WorkerTaskPool({
71
+ workerUrl: resolveRuntimeWorkerUrl(codexCatalogPageWorkerEntrypoint),
72
+ maxWorkers: 1,
73
+ maxPendingTasks: 1,
74
+ maxPendingBytes: Number.MAX_SAFE_INTEGER,
75
+ idleTimeoutMs: 0,
76
+ restartOnError: false
77
+ });
78
+ }
79
+ const attempt = route === "unresolved" ? void 0 : attempts.get(route.id);
80
+ const remainingRows = attempt ? projections.get(attempt)?.remainingRows : 0;
81
+ let catalogRows;
82
+ if (route === "unresolved") {
83
+ catalogRows = /* @__PURE__ */ new Map();
84
+ for (const [id, pending] of attempts) {
85
+ const projection = projections.get(pending);
86
+ if (typeof id === "number" && projection) catalogRows.set(id, projection.remainingRows);
87
+ }
88
+ }
89
+ const bytes = line.byteOffset === 0 && line.byteLength === line.buffer.byteLength && line.buffer instanceof ArrayBuffer ? new Uint8Array(line.buffer) : Uint8Array.from(line);
90
+ const decoded = await this.pool.run({
91
+ bytes,
92
+ route,
93
+ remainingRows,
94
+ catalogRows
95
+ }, {
96
+ inputBytes: bytes.byteLength,
97
+ transferList: (input) => [input.bytes.buffer]
98
+ });
99
+ if (this.closed) return;
100
+ this.continuationRoute = decoded.pending ? route : void 0;
101
+ if (!decoded.pending) this.armIdleRetirement();
102
+ return decoded;
103
+ }
104
+ armIdleRetirement() {
105
+ this.idleTimer = runInCatalogWorkerContext(() => this.setTimeoutFn(() => {
106
+ this.idleTimer = void 0;
107
+ this.retirement = this.pool?.rotate();
108
+ this.retirement?.catch(() => void 0);
109
+ }, CATALOG_WORKER_IDLE_MS));
110
+ this.idleTimer.unref();
111
+ }
112
+ async close(error) {
113
+ this.closed = true;
114
+ this.clearTimeoutFn(this.idleTimer);
115
+ this.idleTimer = void 0;
116
+ this.continuationRoute = void 0;
117
+ await this.retirement?.catch(() => void 0);
118
+ await this.pool?.close(error);
119
+ }
120
+ };
121
+ //#endregion
122
+ //#region extensions/codex/src/app-server/client-diagnostics.ts
123
+ function observeCodexAppServerStderr(stderr, consume) {
124
+ stderr.setEncoding("utf8");
125
+ stderr.on("data", (chunk) => {
126
+ const text = consume(chunk).trim();
127
+ if (text) embeddedAgentLog.debug(`codex app-server stderr: ${text}`);
128
+ });
129
+ stderr.on("error", (error) => embeddedAgentLog.warn("codex app-server stderr stream failed", { error }));
130
+ }
131
+ function appendBoundedTail(current, next, maxLength) {
132
+ const combined = `${current}${next}`;
133
+ return combined.length > maxLength ? sliceUtf16Safe(combined, -maxLength) : combined;
134
+ }
135
+ function buildCodexAppServerExitError(code, signal, stderrTail) {
136
+ const stderrPreview = redactCodexAppServerLinePreview(stderrTail);
137
+ const suffix = stderrPreview ? ` stderr=${JSON.stringify(stderrPreview)}` : "";
138
+ return /* @__PURE__ */ new Error(`codex app-server exited: code=${formatExitValue(code)} signal=${formatExitValue(signal)}${suffix}`);
139
+ }
140
+ function logCodexAppServerParseFailure(value, error, fragmentCount) {
141
+ const linePreview = redactCodexAppServerLinePreview(value);
142
+ const suffix = fragmentCount > 1 ? ` fragments=${fragmentCount}` : "";
143
+ embeddedAgentLog.warn("failed to parse codex app-server message", {
144
+ error,
145
+ errorMessage: coerceErrorMessage(error),
146
+ fragmentCount,
147
+ linePreview,
148
+ consoleMessage: `failed to parse codex app-server message${suffix}: preview=${JSON.stringify(linePreview)}`
149
+ });
150
+ }
151
+ function formatExitValue(value) {
152
+ if (value === null || value === void 0) return "null";
153
+ if (typeof value === "string" || typeof value === "number") return String(value);
154
+ return "unknown";
155
+ }
156
+ //#endregion
157
+ //#region extensions/codex/src/app-server/notification-policy.ts
158
+ const CODEX_APP_SERVER_OPT_OUT_NOTIFICATION_METHODS = [
159
+ "account/login/completed",
160
+ "app/list/updated",
161
+ "command/exec/outputDelta",
162
+ "deprecationNotice",
163
+ "externalAgentConfig/import/completed",
164
+ "externalAgentConfig/import/progress",
165
+ "fs/changed",
166
+ "fuzzyFileSearch/sessionCompleted",
167
+ "fuzzyFileSearch/sessionUpdated",
168
+ "mcpServer/event/stream/notification",
169
+ "mcpServer/oauthLogin/completed",
170
+ "mcpServer/startupStatus/updated",
171
+ "process/exited",
172
+ "process/outputDelta",
173
+ "project/changed",
174
+ "remoteControl/status/changed",
175
+ "thread/environment/connected",
176
+ "thread/environment/disconnected",
177
+ "thread/goal/cleared",
178
+ "thread/project/updated",
179
+ "thread/queue/changed",
180
+ "thread/realtime/closed",
181
+ "thread/realtime/error",
182
+ "thread/realtime/item/completed",
183
+ "thread/realtime/item/started",
184
+ "thread/realtime/item/transcript/delta",
185
+ "thread/realtime/itemAdded",
186
+ "thread/realtime/outputAudio/delta",
187
+ "thread/realtime/sdp",
188
+ "thread/realtime/started",
189
+ "thread/realtime/transcript/delta",
190
+ "thread/realtime/transcript/done",
191
+ "windows/worldWritableWarning",
192
+ "windowsSandbox/setupCompleted",
193
+ "turn/diff/updated",
194
+ "item/fileChange/outputDelta",
195
+ "thread/compacted"
196
+ ];
197
+ //#endregion
198
+ //#region extensions/codex/src/app-server/client-initialize.ts
199
+ function buildCodexAppServerInitializeParams() {
200
+ return {
201
+ clientInfo: {
202
+ name: "openclaw",
203
+ title: "OpenClaw",
204
+ version: OPENCLAW_VERSION
205
+ },
206
+ capabilities: {
207
+ experimentalApi: true,
208
+ optOutNotificationMethods: [...CODEX_APP_SERVER_OPT_OUT_NOTIFICATION_METHODS],
209
+ extensions: {
210
+ "openai/standard-form-input": {},
211
+ "openai/form": {},
212
+ "io.modelcontextprotocol/ui": { mimeTypes: ["text/html;profile=mcp-app"] }
213
+ }
214
+ }
215
+ };
216
+ }
217
+ function buildCodexAppServerRuntimeIdentity(response, serverVersion) {
218
+ const userAgent = normalizeOptionalString(response.userAgent);
219
+ const codexHome = normalizeOptionalString(response.codexHome);
220
+ const platformFamily = normalizeOptionalString(response.platformFamily);
221
+ const platformOs = normalizeOptionalString(response.platformOs);
222
+ return {
223
+ serverVersion,
224
+ ...userAgent ? { userAgent } : {},
225
+ ...codexHome ? { codexHome } : {},
226
+ ...platformFamily ? { platformFamily } : {},
227
+ ...platformOs ? { platformOs } : {}
228
+ };
32
229
  }
33
230
  //#endregion
34
231
  //#region extensions/codex/src/app-server/client-response.ts
35
232
  /** Settles one wire attempt and reports newly observed native execution. */
36
- function dispatchCodexAppServerResponse(response, attempts, catalogResponses, source) {
233
+ function dispatchCodexAppServerResponse(response, attempts, catalogResponses, source, previewStates) {
37
234
  const pending = attempts.get(response.id);
38
235
  if (!pending) return false;
39
236
  attempts.delete(response.id);
@@ -43,112 +240,187 @@ function dispatchCodexAppServerResponse(response, attempts, catalogResponses, so
43
240
  return false;
44
241
  }
45
242
  const nativeExecution = pending.method === "thread/backgroundTerminals/list" && isJsonObject(response.result) && Array.isArray(response.result.data) && response.result.data.length > 0;
46
- if (catalogResponses.has(pending) && isJsonObject(response.result) && Array.isArray(response.result.data)) {
47
- const projection = catalogResponses.get(pending);
48
- try {
49
- response.result = projectCodexCatalogNativeResponse(response.result, sanitizeTerminalText, projection?.preview, projection?.remainingRows);
50
- } catch (error) {
51
- pending.reject(error instanceof Error ? error : new Error("Codex catalog projection failed", { cause: error }), false);
52
- return false;
243
+ const cache = catalogResponses.get(pending)?.preview;
244
+ if (cache && previewStates && isJsonObject(response.result) && Array.isArray(response.result.data)) try {
245
+ for (const [index, row] of response.result.data.entries()) if (isJsonObject(row) && typeof row.id === "string" && row.ephemeral !== true) {
246
+ const preview = reuseCodexCatalogPreview({
247
+ id: row.id,
248
+ path: typeof row.path === "string" ? row.path : null,
249
+ updatedAt: typeof row.updatedAt === "number" ? row.updatedAt : null,
250
+ recencyAt: typeof row.recencyAt === "number" ? row.recencyAt : null
251
+ }, previewStates[index], cache);
252
+ if (preview !== void 0) row.preview = preview;
53
253
  }
254
+ } catch (error) {
255
+ pending.reject(error instanceof Error ? error : new Error("Codex catalog projection failed", { cause: error }), false);
256
+ return false;
54
257
  }
55
258
  recordCodexCatalogResponseSource(pending.method, response.result, source);
56
259
  pending.resolve(response.result);
57
260
  return nativeExecution;
58
261
  }
59
262
  //#endregion
60
- //#region extensions/codex/src/app-server/dynamic-tool-response-state.ts
61
- /** Retains the host-owned app preview without adding it to Codex's response payload. */
62
- function withDynamicToolTranscriptDetails(response, details) {
63
- if (details === void 0) return response;
64
- Object.defineProperty(response, "transcriptDetails", {
65
- configurable: true,
66
- enumerable: false,
67
- value: details
68
- });
69
- return response;
70
- }
71
- function withDynamicToolTerminalResolution(response, terminalResolution) {
72
- if (terminalResolution) {
73
- Object.defineProperties(response, {
74
- terminalResolution: {
75
- configurable: true,
76
- enumerable: false,
77
- value: terminalResolution
78
- },
79
- executionStarted: {
80
- configurable: true,
81
- enumerable: false,
82
- value: terminalResolution.executionStarted
83
- },
84
- ...terminalResolution.executedArguments ? { executedArguments: {
85
- configurable: true,
86
- enumerable: false,
87
- value: terminalResolution.executedArguments
88
- } } : {}
89
- });
90
- withDynamicToolSideEffectEvidence(response, terminalResolution.sideEffectEvidence);
91
- }
92
- return response;
93
- }
94
- function withDynamicToolExecutionState(response, state) {
95
- Object.defineProperties(response, {
96
- executedArguments: {
97
- configurable: true,
98
- enumerable: false,
99
- value: state.executedArguments
263
+ //#region extensions/codex/src/app-server/request-attempt.ts
264
+ /** One caller per wire attempt; local waiter expiry need not imply a native response. */
265
+ function createCodexRequestAttempt(params) {
266
+ let pending = true;
267
+ let mayHaveWritten = false;
268
+ let waiter;
269
+ const diagnostics = params.diagnosticIdentity ? {
270
+ ...params.diagnosticIdentity,
271
+ attemptCreatedAtMs: performance.now(),
272
+ firstPossibleWriteAtMs: null,
273
+ wireOutcomeAtWaiterSettlement: "retained-pending",
274
+ wireObservedAtMs: null
275
+ } : void 0;
276
+ const finish = (outcome) => {
277
+ if (!pending) return false;
278
+ pending = false;
279
+ if (diagnostics) {
280
+ diagnostics.wireOutcomeAtWaiterSettlement = outcome;
281
+ diagnostics.wireObservedAtMs = performance.now();
282
+ }
283
+ params.onSettled();
284
+ return true;
285
+ };
286
+ const currentWaiterError = () => {
287
+ if (!params.retainWritten || !waiter) return;
288
+ if (waiter.signal?.aborted) return {
289
+ error: params.cancellationError("aborted", mayHaveWritten, waiter.signal.reason),
290
+ outcome: "aborted"
291
+ };
292
+ if (waiter.deadline !== void 0 && performance.now() >= waiter.deadline) return {
293
+ error: params.cancellationError("timed out", mayHaveWritten),
294
+ outcome: "timed-out"
295
+ };
296
+ };
297
+ return {
298
+ method: params.method,
299
+ get pending() {
300
+ return pending;
301
+ },
302
+ wait(options, deadline) {
303
+ const { timeoutMs, signal, overloadAttemptOrdinal } = options;
304
+ let observe = options.attemptWaiterFinished;
305
+ return new Promise((resolve, reject) => {
306
+ if (!pending) {
307
+ reject(/* @__PURE__ */ new Error("Codex request attempt is already settled"));
308
+ return;
309
+ }
310
+ let timer;
311
+ let removeAbort;
312
+ const waiterAttachedAtMs = diagnostics && observe ? performance.now() : 0;
313
+ const cleanup = () => {
314
+ clearTimeout(timer);
315
+ timer = void 0;
316
+ removeAbort?.();
317
+ removeAbort = void 0;
318
+ };
319
+ const detach = (waiterOutcome) => {
320
+ if (!waiter) return false;
321
+ waiter = void 0;
322
+ cleanup();
323
+ if (!params.retainWritten || !mayHaveWritten) finish(mayHaveWritten ? "correlation-closed" : "not-written");
324
+ const callback = observe;
325
+ observe = void 0;
326
+ if (diagnostics && callback) try {
327
+ callback({
328
+ ...diagnostics,
329
+ waiterOrdinal: 1,
330
+ disposition: "new",
331
+ overloadAttemptOrdinal,
332
+ waiterAttachedAtMs,
333
+ waiterSettledAtMs: performance.now(),
334
+ waiterOutcome
335
+ });
336
+ } catch {}
337
+ return true;
338
+ };
339
+ const localWaiter = {
340
+ resolve: (value) => {
341
+ if (!detach("resolved")) return;
342
+ resolve(value);
343
+ },
344
+ reject: (error, outcome) => {
345
+ if (detach(outcome)) reject(error);
346
+ },
347
+ signal,
348
+ deadline
349
+ };
350
+ waiter = localWaiter;
351
+ if (params.retainWritten && deadline !== void 0 && performance.now() >= deadline) {
352
+ localWaiter.reject(params.cancellationError("timed out", mayHaveWritten), "timed-out");
353
+ return;
354
+ }
355
+ if (timeoutMs && Number.isFinite(timeoutMs) && timeoutMs > 0) {
356
+ const remaining = params.retainWritten && deadline !== void 0 ? deadline - performance.now() : timeoutMs;
357
+ timer = setTimeout(() => localWaiter.reject(params.cancellationError("timed out", mayHaveWritten), "timed-out"), Math.max(params.retainWritten ? 1 : 100, remaining));
358
+ timer.unref?.();
359
+ }
360
+ if (signal) {
361
+ const abort = () => localWaiter.reject(params.cancellationError("aborted", mayHaveWritten, signal.reason), "aborted");
362
+ signal.addEventListener("abort", abort, { once: true });
363
+ removeAbort = () => signal.removeEventListener("abort", abort);
364
+ if (signal.aborted) abort();
365
+ }
366
+ });
367
+ },
368
+ resolve(value) {
369
+ if (!finish("native-ok")) return;
370
+ params.onResponse?.(mayHaveWritten);
371
+ const error = currentWaiterError();
372
+ if (error) waiter?.reject(error.error, error.outcome);
373
+ else waiter?.resolve(value);
374
+ },
375
+ reject(error, definitelyNotEnqueued = false) {
376
+ if (finish(definitelyNotEnqueued ? "ingress-rejected" : "native-error")) {
377
+ if (definitelyNotEnqueued) mayHaveWritten = false;
378
+ params.onResponse?.(mayHaveWritten);
379
+ const current = currentWaiterError();
380
+ waiter?.reject(current?.error ?? params.localError(error, mayHaveWritten), current?.outcome ?? "native-error");
381
+ }
382
+ },
383
+ close(error) {
384
+ if (finish("correlation-closed")) waiter?.reject(params.localError(error, mayHaveWritten), "client-closed");
385
+ },
386
+ failLocal(error) {
387
+ if (!pending) return;
388
+ if (!params.retainWritten || !mayHaveWritten) finish(mayHaveWritten ? "correlation-closed" : "not-written");
389
+ waiter?.reject(params.localError(error, mayHaveWritten), "local-failed");
100
390
  },
101
- executionStarted: {
102
- configurable: true,
103
- enumerable: false,
104
- value: state.executionStarted
391
+ markWritten() {
392
+ mayHaveWritten = true;
393
+ if (diagnostics && diagnostics.firstPossibleWriteAtMs === null) diagnostics.firstPossibleWriteAtMs = performance.now();
105
394
  }
106
- });
107
- return withDynamicToolSideEffectEvidence(response, state.sideEffectEvidence === true);
108
- }
109
- function withDynamicToolSideEffectEvidence(response, sideEffectEvidence) {
110
- if (!sideEffectEvidence) {
111
- delete response.sideEffectEvidence;
112
- return response;
113
- }
114
- Object.defineProperty(response, "sideEffectEvidence", {
115
- configurable: true,
116
- enumerable: false,
117
- value: true
118
- });
119
- return response;
395
+ };
120
396
  }
397
+ //#endregion
398
+ //#region extensions/codex/src/app-server/dynamic-tool-response-state.ts
121
399
  function createFailedDynamicToolResponse(message, options) {
122
- const response = {
400
+ return {
123
401
  contentItems: [{
124
402
  type: "inputText",
125
403
  text: message
126
404
  }],
127
- success: false
405
+ success: false,
406
+ diagnosticTerminalReason: options?.terminalReason ?? "failed",
407
+ diagnosticTerminalType: "error",
408
+ executionStarted: options?.executionStarted,
409
+ executedArguments: options?.executedArguments,
410
+ sideEffectEvidence: options?.sideEffectEvidence === true || void 0
128
411
  };
129
- Object.defineProperties(response, {
130
- diagnosticTerminalReason: {
131
- configurable: true,
132
- enumerable: false,
133
- value: options?.terminalReason ?? "failed"
134
- },
135
- diagnosticTerminalType: {
136
- configurable: true,
137
- enumerable: false,
138
- value: "error"
412
+ }
413
+ function failedToolResult(message, status = "failed") {
414
+ return {
415
+ content: [{
416
+ type: "text",
417
+ text: message
418
+ }],
419
+ details: {
420
+ status,
421
+ error: message
139
422
  }
140
- });
141
- if (options?.executionStarted !== void 0) Object.defineProperty(response, "executionStarted", {
142
- configurable: true,
143
- enumerable: false,
144
- value: options.executionStarted
145
- });
146
- if (options?.executedArguments !== void 0) Object.defineProperty(response, "executedArguments", {
147
- configurable: true,
148
- enumerable: false,
149
- value: options.executedArguments
150
- });
151
- return withDynamicToolSideEffectEvidence(response, options?.sideEffectEvidence === true);
423
+ };
152
424
  }
153
425
  //#endregion
154
426
  //#region extensions/codex/src/app-server/tool-abort-terminal-reason.ts
@@ -178,21 +450,13 @@ function resolveCodexToolAbortTerminalReason(signal) {
178
450
  }
179
451
  //#endregion
180
452
  //#region extensions/codex/src/app-server/dynamic-tool-execution.ts
181
- /**
182
- * Timeout, terminal-release, and diagnostic helpers for Codex dynamic tool
183
- * calls.
184
- */
185
- /** Default timeout for Codex dynamic tool calls. */
186
453
  const CODEX_DYNAMIC_TOOL_TIMEOUT_MS = 9e4;
187
- /** Hard cap for ordinary per-call Codex dynamic tool timeout overrides. */
188
454
  const CODEX_DYNAMIC_TOOL_MAX_TIMEOUT_MS = 6e5;
189
455
  const CODEX_DYNAMIC_TOOL_TIMEOUT_SECONDS_GRACE_MS = 3e4;
190
456
  const CODEX_DYNAMIC_IMAGE_GENERATION_TOOL_TIMEOUT_MS = 12e4;
191
457
  const CODEX_DYNAMIC_COMPUTER_GATEWAY_TIMEOUT_MS = 3e4;
192
458
  const CODEX_DYNAMIC_COMPUTER_COMPLETION_GRACE_MS = 3e4;
193
- /** Timeout for image-understanding style dynamic tool calls. */
194
459
  const CODEX_DYNAMIC_IMAGE_TOOL_TIMEOUT_MS = 6e4;
195
- /** Timeout for message-delivery dynamic tool calls. */
196
460
  const CODEX_DYNAMIC_MESSAGE_TOOL_TIMEOUT_MS = 6e5;
197
461
  /** Outer default for collector waits: full swarm budget plus completion grace. */
198
462
  const CODEX_DYNAMIC_AGENTS_WAIT_TOOL_TIMEOUT_MS = 63e4;
@@ -244,11 +508,13 @@ function formatDynamicToolTimeoutDetails(params) {
244
508
  }
245
509
  };
246
510
  }
247
- /**
248
- * Runs a dynamic tool call with run-abort and the budget prepared by
249
- * resolveDynamicToolCallTimeoutMs, preserving tool-specific completion grace.
250
- */
251
511
  async function handleDynamicToolCallWithTimeout(params) {
512
+ return await runWithAsyncWorkResources((onAcquired) => executeDynamicToolCallWithTimeout(params, (release) => onAcquired({
513
+ release,
514
+ releaseBeforeResultWhenIdle: true
515
+ })));
516
+ }
517
+ async function executeDynamicToolCallWithTimeout(params, retainCleanup) {
252
518
  let didNotifyAgentToolResult = false;
253
519
  const conservativeRaceResponses = /* @__PURE__ */ new WeakSet();
254
520
  const finalizeTerminal = (response) => {
@@ -265,11 +531,18 @@ async function handleDynamicToolCallWithTimeout(params) {
265
531
  arguments: response.executedArguments ?? executionSnapshot?.executedArguments ?? params.call.arguments,
266
532
  ...params.toolMeta ? { meta: params.toolMeta } : {},
267
533
  ...ownerKey ? { ownerMutation: { ownerKey } } : {},
534
+ replaySafe: ownerKey ? false : response.replaySafe,
268
535
  ...observedExecutionStarted !== void 0 ? { executionStarted: observedExecutionStarted } : {},
269
536
  outcome: response.success ? "success" : "failure",
270
537
  ...!response.success ? { failure: { error: readDynamicToolResponseText(response) } } : {}
271
538
  });
272
- return withDynamicToolTerminalResolution(response, terminalResolution);
539
+ if (terminalResolution) {
540
+ response.terminalResolution = terminalResolution;
541
+ response.executionStarted = terminalResolution.executionStarted;
542
+ response.executedArguments = terminalResolution.executedArguments ?? response.executedArguments;
543
+ response.sideEffectEvidence = terminalResolution.sideEffectEvidence || void 0;
544
+ }
545
+ return response;
273
546
  };
274
547
  const createFailedAfterPossibleDispatch = (message, terminalReason) => {
275
548
  const response = createFailedDynamicToolResponse(message, {
@@ -293,16 +566,7 @@ async function handleDynamicToolCallWithTimeout(params) {
293
566
  const notifyFailedToolResult = (message, terminalReason = "failed") => {
294
567
  notifyAgentToolResult({
295
568
  toolName: params.call.tool,
296
- result: {
297
- content: [{
298
- type: "text",
299
- text: message
300
- }],
301
- details: {
302
- status: terminalReason,
303
- error: message
304
- }
305
- },
569
+ result: failedToolResult(message, terminalReason),
306
570
  isError: true
307
571
  });
308
572
  };
@@ -319,15 +583,26 @@ async function handleDynamicToolCallWithTimeout(params) {
319
583
  const controller = new AbortController();
320
584
  let timeout;
321
585
  let timedOut = false;
586
+ let toolCallSettled = false;
587
+ let completedSuccessfully = false;
588
+ let operationReleased = false;
322
589
  let resolveAbort;
323
590
  const abortFromRun = () => {
324
591
  const message = "OpenClaw dynamic tool call aborted.";
325
592
  const terminalReason = resolveCodexToolAbortTerminalReason(params.signal);
326
- params.onFallbackSelected?.();
327
593
  controller.abort(params.signal.reason ?? /* @__PURE__ */ new Error(message));
594
+ if (toolCallSettled) return;
595
+ params.onFallbackSelected?.();
328
596
  notifyFailedToolResult(message, terminalReason);
329
597
  resolveAbort?.(createFailedAfterPossibleDispatch(message, terminalReason));
330
598
  };
599
+ const releaseOperation = () => {
600
+ if (operationReleased) return;
601
+ operationReleased = true;
602
+ params.signal.removeEventListener("abort", abortFromRun);
603
+ if (!controller.signal.aborted) controller.abort(/* @__PURE__ */ new Error("OpenClaw dynamic tool call finished."));
604
+ };
605
+ retainCleanup(releaseOperation);
331
606
  const abortPromise = new Promise((resolve) => {
332
607
  resolveAbort = resolve;
333
608
  });
@@ -365,7 +640,9 @@ async function handleDynamicToolCallWithTimeout(params) {
365
640
  timeoutPromise
366
641
  ]);
367
642
  if (!response.success && !didNotifyAgentToolResult) notifyFailedToolResult(readDynamicToolResponseText(response), response.diagnosticTerminalReason ?? "failed");
368
- return finalizeTerminal(response);
643
+ const terminal = finalizeTerminal(response);
644
+ completedSuccessfully = terminal.success;
645
+ return terminal;
369
646
  } catch (error) {
370
647
  const terminalReason = params.signal.aborted ? resolveCodexToolAbortTerminalReason(params.signal) : resolveToolExecutionErrorKind(error);
371
648
  const message = formatToolExecutionErrorMessage(error, "OpenClaw dynamic tool call failed.");
@@ -373,9 +650,9 @@ async function handleDynamicToolCallWithTimeout(params) {
373
650
  return finalizeTerminal(createFailedAfterPossibleDispatch(message, terminalReason));
374
651
  } finally {
375
652
  if (timeout) clearTimeout(timeout);
376
- params.signal.removeEventListener("abort", abortFromRun);
653
+ toolCallSettled = true;
377
654
  resolveAbort = void 0;
378
- if (!timedOut && !controller.signal.aborted) controller.abort(/* @__PURE__ */ new Error("OpenClaw dynamic tool call finished."));
655
+ if (!completedSuccessfully || timedOut || controller.signal.aborted) releaseOperation();
379
656
  }
380
657
  }
381
658
  function readDynamicToolResponseText(response) {
@@ -392,38 +669,31 @@ function toCodexDynamicToolProtocolResponse(response) {
392
669
  function toCodexDynamicToolProgressResponse(response, protocolResponse) {
393
670
  const transcriptDetails = isJsonObject(response.transcriptDetails) ? response.transcriptDetails : void 0;
394
671
  const mcpAppPreview = isJsonObject(transcriptDetails?.mcpAppPreview) ? transcriptDetails.mcpAppPreview : void 0;
395
- const progressDetails = mcpAppPreview ? { mcpAppPreview } : void 0;
396
- if (response.asyncStarted !== true && progressDetails === void 0) return protocolResponse;
672
+ if (response.asyncStarted !== true && !mcpAppPreview) return protocolResponse;
397
673
  return {
398
674
  ...protocolResponse,
399
- ...progressDetails ? { details: progressDetails } : {},
400
- ...response.asyncStarted === true ? { details: {
401
- ...progressDetails,
675
+ details: response.asyncStarted === true ? {
676
+ ...mcpAppPreview ? { mcpAppPreview } : {},
402
677
  async: true,
403
678
  status: "started"
404
- } } : {}
679
+ } : { mcpAppPreview }
405
680
  };
406
681
  }
407
- /** Decides whether a terminal dynamic tool response can release the Codex turn. */
408
682
  function shouldReleaseTurnAfterTerminalDynamicTool(state) {
409
683
  return !state.completed && !state.aborted && state.responseSuccess && !state.currentTurnHadNonTerminalDynamicToolResult && state.activeAppServerTurnRequests === 0 && state.activeTurnItemIdsCount === 0 && state.pendingOpenClawDynamicToolCompletionIdsCount === 0;
410
684
  }
411
- /** Returns true when a non-async result should block terminal-release shortcuts. */
412
685
  function shouldBlockTerminalReleaseForNonTerminalDynamicToolResult(response) {
413
686
  return response.asyncStarted !== true;
414
687
  }
415
- /** Resolves whether terminal diagnostic state should release, wait, or stay idle. */
416
688
  function resolveTerminalDynamicToolBatchAction(state) {
417
689
  if (state.activeAppServerTurnRequests > 0 || state.activeTurnItemIdsCount > 0 || state.pendingOpenClawDynamicToolCompletionIdsCount > 0) return "wait";
418
690
  if (state.currentTurnHadNonTerminalDynamicToolResult) return "clear-nonterminal-batch";
419
691
  if (state.hasPendingTerminalDynamicToolRelease) return "release-pending-terminal";
420
692
  return "idle";
421
693
  }
422
- /** Returns true for diagnostic events that terminate a dynamic tool call. */
423
694
  function isDynamicToolTerminalDiagnosticEvent(event) {
424
695
  return event.type === "tool.execution.completed" || event.type === "tool.execution.error" || event.type === "tool.execution.blocked";
425
696
  }
426
- /** Matches terminal diagnostics to a specific dynamic tool call id/name. */
427
697
  function isMatchingDynamicToolTerminalDiagnostic(params) {
428
698
  if (params.event.toolCallId !== params.call.callId || params.event.toolName !== params.call.tool) return false;
429
699
  if (params.runId !== void 0) return params.event.runId === params.runId;
@@ -431,7 +701,6 @@ function isMatchingDynamicToolTerminalDiagnostic(params) {
431
701
  if (params.sessionKey !== void 0) return params.event.sessionKey === params.sessionKey;
432
702
  return params.event.runId === void 0 && params.event.sessionId === void 0 && params.event.sessionKey === void 0;
433
703
  }
434
- /** Checks pending diagnostics for a terminal event matching a tool call. */
435
704
  function hasPendingDynamicToolTerminalDiagnostic(params) {
436
705
  return hasPendingInternalDiagnosticEvent((event) => {
437
706
  if (!isDynamicToolTerminalDiagnosticEvent(event)) return false;
@@ -444,7 +713,6 @@ function hasPendingDynamicToolTerminalDiagnostic(params) {
444
713
  });
445
714
  });
446
715
  }
447
- /** Resolves per-tool timeout, applying media/message defaults and hard caps. */
448
716
  function resolveDynamicToolCallTimeoutMs(params) {
449
717
  const args = isJsonObject(params.call.arguments) ? params.call.arguments : void 0;
450
718
  if (params.call.tool === "node_exec") {
@@ -459,11 +727,8 @@ function resolveDynamicToolCallTimeoutMs(params) {
459
727
  }
460
728
  if (params.call.tool === "computer") return clampDynamicToolTimeoutMs(readComputerToolTimeoutMs(params.call.arguments));
461
729
  if (params.call.tool === "message") return CODEX_DYNAMIC_MESSAGE_TOOL_TIMEOUT_MS;
462
- if (params.call.tool === "agents_wait") {
463
- const requestedMs = readDynamicToolCallTimeoutMs(params.call.arguments) ?? readConfiguredDynamicToolTimeoutMs(params.call.tool, params.config) ?? CODEX_DYNAMIC_AGENTS_WAIT_TOOL_TIMEOUT_MS;
464
- return Math.max(1, Math.min(63e4, Math.floor(requestedMs)));
465
- }
466
- return clampDynamicToolTimeoutMs(readDynamicToolCallTimeoutMs(params.call.arguments) ?? readConfiguredDynamicToolTimeoutMs(params.call.tool, params.config) ?? CODEX_DYNAMIC_TOOL_TIMEOUT_MS);
730
+ const isCollectorWait = params.call.tool === "agents_wait";
731
+ return clampDynamicToolTimeoutMs(readDynamicToolCallTimeoutMs(params.call.arguments) ?? readConfiguredDynamicToolTimeoutMs(params.call.tool, params.config) ?? (isCollectorWait ? CODEX_DYNAMIC_AGENTS_WAIT_TOOL_TIMEOUT_MS : CODEX_DYNAMIC_TOOL_TIMEOUT_MS), isCollectorWait ? CODEX_DYNAMIC_AGENTS_WAIT_TOOL_TIMEOUT_MS : CODEX_DYNAMIC_TOOL_MAX_TIMEOUT_MS);
467
732
  }
468
733
  /** Transport guard stays outside the handler's bounded tool wait and completion grace. */
469
734
  function resolveDynamicToolServerRequestTimeoutMs(call) {
@@ -509,8 +774,8 @@ function readDynamicToolTimeoutSecondsAsMs(value) {
509
774
  function readPositiveFiniteTimeoutMs(value) {
510
775
  return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : void 0;
511
776
  }
512
- function clampDynamicToolTimeoutMs(timeoutMs) {
513
- return Math.max(1, Math.min(CODEX_DYNAMIC_TOOL_MAX_TIMEOUT_MS, Math.floor(timeoutMs)));
777
+ function clampDynamicToolTimeoutMs(timeoutMs, maximum = CODEX_DYNAMIC_TOOL_MAX_TIMEOUT_MS) {
778
+ return Math.max(1, Math.min(maximum, Math.floor(timeoutMs)));
514
779
  }
515
780
  //#endregion
516
781
  //#region extensions/codex/src/app-server/elicitation-response.ts
@@ -2792,10 +3057,15 @@ var TurnStartResponse_default = {
2792
3057
  };
2793
3058
  //#endregion
2794
3059
  //#region extensions/codex/src/app-server/protocol-validators.ts
2795
- /**
2796
- * Runtime validators for Codex app-server protocol payloads, including schema
2797
- * normalization for generated JSON Schema before TypeBox compilation.
2798
- */
3060
+ function readSupervisionResponseThreadId(value) {
3061
+ const thread = isRecord(value) ? value.thread : void 0;
3062
+ return isRecord(thread) ? thread.id : void 0;
3063
+ }
3064
+ function resolveCodexThreadRolloutPath(thread) {
3065
+ const rolloutPath = thread.path?.trim();
3066
+ if (!rolloutPath || !path.isAbsolute(rolloutPath) || path.extname(rolloutPath) !== ".jsonl" || !path.basename(rolloutPath).includes(thread.id)) return;
3067
+ return rolloutPath;
3068
+ }
2799
3069
  const externalDefinitionRefPrefix = "./CodexAppServerProtocolDefinitions.json#/definitions/";
2800
3070
  const rootExternalDefinitionRefPrefix = "./v2/CodexAppServerProtocolDefinitions.json#/definitions/";
2801
3071
  const localDefinitionRefPrefix = "#/definitions/";
@@ -2837,17 +3107,12 @@ function rewriteDefinitionRefs(value, externalRefPrefix) {
2837
3107
  if (!isRecord(value)) return value;
2838
3108
  return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, key === "$ref" && typeof entry === "string" && entry.startsWith(externalRefPrefix) ? `${localDefinitionRefPrefix}${entry.slice(externalRefPrefix.length)}` : rewriteDefinitionRefs(entry, externalRefPrefix)]));
2839
3109
  }
2840
- const dynamicToolCallParamsSchema = materializeCodexSchema(DynamicToolCallParams_default, rootExternalDefinitionRefPrefix);
2841
- const errorNotificationSchema = materializeCodexSchema(ErrorNotification_default);
2842
- const modelListResponseSchema = materializeCodexSchema(ModelListResponse_default);
2843
- const threadResumeResponseSchema = materializeCodexSchema(ThreadResumeResponse_default);
2844
- const threadStartResponseSchema = materializeCodexSchema(ThreadStartResponse_default);
2845
- const turnCompletedNotificationSchema = materializeCodexSchema(TurnCompletedNotification_default);
2846
- const turnStartResponseSchema = materializeCodexSchema(TurnStartResponse_default);
2847
- function compileCodexSchema(schema) {
3110
+ function compileCodexSchema(rawSchema, externalRefPrefix) {
3111
+ const schema = materializeCodexSchema(rawSchema, externalRefPrefix);
2848
3112
  if (typeof schema !== "boolean" && !isRecord(schema)) throw new TypeError("Generated Codex schema must be an object or boolean");
2849
3113
  const validator = Compile(normalizeJsonSchemaForTypeBox(schema));
2850
3114
  return {
3115
+ schema,
2851
3116
  check: (value) => validator.Check(value),
2852
3117
  errors: (value) => [...validator.Errors(value)]
2853
3118
  };
@@ -2887,10 +3152,7 @@ function applySchemaDefaults(schema, value, root = schema, resolvingRefs = /* @_
2887
3152
  resolvingRefs.delete(schema.$ref);
2888
3153
  }
2889
3154
  }
2890
- for (const key of ["allOf"]) {
2891
- const branches = schema[key];
2892
- if (Array.isArray(branches)) for (const branch of branches) nextValue = applySchemaDefaults(branch, nextValue, root, resolvingRefs);
2893
- }
3155
+ if (Array.isArray(schema.allOf)) for (const branch of schema.allOf) nextValue = applySchemaDefaults(branch, nextValue, root, resolvingRefs);
2894
3156
  if (schemaTypeIncludes(schema, "object") && isRecord(nextValue) && isRecord(schema.properties)) {
2895
3157
  for (const [key, propertySchema] of Object.entries(schema.properties)) {
2896
3158
  const currentValue = nextValue[key];
@@ -2909,27 +3171,21 @@ function normalizeWithDefaults(schema, value) {
2909
3171
  if (value === void 0 || value === null) return value;
2910
3172
  return applySchemaDefaults(schema, structuredClone(value));
2911
3173
  }
2912
- const validateDynamicToolCallParams = compileCodexSchema(dynamicToolCallParamsSchema);
2913
- const validateErrorNotification = compileCodexSchema(errorNotificationSchema);
2914
- const validateModelListResponse = compileCodexSchema(modelListResponseSchema);
2915
- const validateThreadResumeResponse = compileCodexSchema(threadResumeResponseSchema);
2916
- const validateThreadStartResponse = compileCodexSchema(threadStartResponseSchema);
2917
- const validateTurnCompletedNotification = compileCodexSchema(turnCompletedNotificationSchema);
2918
- const validateTurnStartResponse = compileCodexSchema(turnStartResponseSchema);
2919
- /** Asserts and normalizes a Codex thread/start response. */
3174
+ const validateDynamicToolCallParams = compileCodexSchema(DynamicToolCallParams_default, rootExternalDefinitionRefPrefix);
3175
+ const validateErrorNotification = compileCodexSchema(ErrorNotification_default);
3176
+ const validateModelListResponse = compileCodexSchema(ModelListResponse_default);
3177
+ const validateThreadResumeResponse = compileCodexSchema(ThreadResumeResponse_default);
3178
+ const validateThreadStartResponse = compileCodexSchema(ThreadStartResponse_default);
3179
+ const validateTurnCompletedNotification = compileCodexSchema(TurnCompletedNotification_default);
3180
+ const validateTurnStartResponse = compileCodexSchema(TurnStartResponse_default);
2920
3181
  function assertCodexThreadStartResponse(value) {
2921
- const normalized = normalizeWithDefaults(threadStartResponseSchema, value);
2922
- return assertCodexShape(validateThreadStartResponse, normalized, "thread/start response");
3182
+ return assertCodexShape(validateThreadStartResponse, value, "thread/start response");
2923
3183
  }
2924
- /** Asserts and normalizes a Codex thread/fork response. */
2925
3184
  function assertCodexThreadForkResponse(value) {
2926
- const normalized = normalizeWithDefaults(threadStartResponseSchema, value);
2927
- return assertCodexShape(validateThreadStartResponse, normalized, "thread/fork response");
3185
+ return assertCodexShape(validateThreadStartResponse, value, "thread/fork response");
2928
3186
  }
2929
- /** Asserts and normalizes a Codex thread/resume response. */
2930
3187
  function assertCodexThreadResumeResponse(value) {
2931
- const normalized = normalizeWithDefaults(threadResumeResponseSchema, value);
2932
- return assertCodexShape(validateThreadResumeResponse, normalized, "thread/resume response");
3188
+ return assertCodexShape(validateThreadResumeResponse, value, "thread/resume response");
2933
3189
  }
2934
3190
  var CodexThreadDirectInputError = class extends Error {
2935
3191
  constructor(threadId) {
@@ -2941,16 +3197,15 @@ var CodexThreadDirectInputError = class extends Error {
2941
3197
  function assertCodexThreadAcceptsDirectInput(thread) {
2942
3198
  if (thread.canAcceptDirectInput === false) throw new CodexThreadDirectInputError(thread.id);
2943
3199
  }
2944
- /** Asserts and normalizes a Codex turn/start response. */
2945
3200
  function assertCodexTurnStartResponse(value) {
2946
- const normalized = normalizeWithDefaults(turnStartResponseSchema, normalizeTurnEnvelope(value));
2947
- return assertCodexShape(validateTurnStartResponse, normalized, "turn/start response");
3201
+ return assertCodexShape(validateTurnStartResponse, value, "turn/start response");
2948
3202
  }
2949
- /** Only the current text prompt may be echoed; capabilities and historical items are not passive. */
2950
- function assertCodexPassiveTurnItems(items, prompt, taskLabel) {
3203
+ /** Prompt echoes and attested managed-hook continuations cannot admit native capabilities. */
3204
+ function assertCodexPassiveTurnItems(items, prompt, taskLabel, options = {}) {
2951
3205
  let promptEchoSeen = false;
2952
3206
  for (const item of items) {
2953
3207
  if (item.type === "agentMessage" || item.type === "reasoning") continue;
3208
+ if (item.type === "hookPrompt" && options.allowManagedHookPrompts === true && Array.isArray(item.fragments) && item.fragments.length > 0 && item.fragments.every((fragment) => isJsonObject(fragment) && typeof fragment.text === "string" && typeof fragment.hookRunId === "string" && fragment.hookRunId.trim().length > 0)) continue;
2954
3209
  if (item.type === "userMessage" && !promptEchoSeen) {
2955
3210
  const content = Array.isArray(item.content) ? item.content : [];
2956
3211
  const input = content[0];
@@ -2962,80 +3217,30 @@ function assertCodexPassiveTurnItems(items, prompt, taskLabel) {
2962
3217
  throw new Error(`Codex ${taskLabel} returned unexpected native item: ${item.type}`);
2963
3218
  }
2964
3219
  }
2965
- /** Reads Codex dynamic-tool call params, returning undefined for invalid payloads. */
2966
3220
  function readCodexDynamicToolCallParams(value) {
2967
- return readCodexShape(validateDynamicToolCallParams, normalizeWithDefaults(dynamicToolCallParamsSchema, value));
3221
+ return readCodexShape(validateDynamicToolCallParams, value);
2968
3222
  }
2969
- /** Reads a Codex error notification payload if it matches the protocol schema. */
2970
3223
  function readCodexErrorNotification(value) {
2971
- return readCodexShape(validateErrorNotification, normalizeWithDefaults(errorNotificationSchema, value));
3224
+ return readCodexShape(validateErrorNotification, value);
2972
3225
  }
2973
- /** Asserts and normalizes a Codex model/list response. */
2974
3226
  function assertCodexModelListResponse(value) {
2975
- return assertCodexShape(validateModelListResponse, normalizeWithDefaults(modelListResponseSchema, value), "model/list response");
2976
- }
2977
- /** Reads and normalizes a Codex turn object. */
2978
- function readCodexTurn(value) {
2979
- return readCodexShape(validateTurnStartResponse, normalizeWithDefaults(turnStartResponseSchema, { turn: normalizeTurn(value) }))?.turn;
3227
+ return assertCodexShape(validateModelListResponse, value, "model/list response");
2980
3228
  }
2981
- /** Reads a Codex turn/completed notification payload if it matches the protocol schema. */
2982
3229
  function readCodexTurnCompletedNotification(value) {
2983
- return readCodexShape(validateTurnCompletedNotification, normalizeWithDefaults(turnCompletedNotificationSchema, normalizeTurnEnvelope(value)));
3230
+ const notification = readCodexShape(validateTurnCompletedNotification, value);
3231
+ return notification?.turn.status === "inProgress" ? void 0 : notification;
3232
+ }
3233
+ function assertExactSupervisionModelSelection(value, expected) {
3234
+ if (value.model !== expected.model || value.modelProvider !== expected.modelProvider) throw new Error(`Codex supervision ${expected.operation} changed native model selection: ${value.modelProvider ?? "unknown"}/${value.model ?? "unknown"}`);
2984
3235
  }
2985
3236
  function assertCodexShape(validate, value, label) {
2986
- if (validate.check(value)) return value;
2987
- throw new Error(`Invalid Codex app-server ${label}: ${formatValidationErrors(validate, value)}`);
3237
+ const normalized = normalizeWithDefaults(validate.schema, value);
3238
+ if (validate.check(normalized)) return normalized;
3239
+ throw new Error(`Invalid Codex app-server ${label}: ${formatValidationErrors(validate, normalized)}`);
2988
3240
  }
2989
3241
  function readCodexShape(validate, value) {
2990
- return validate.check(value) ? value : void 0;
2991
- }
2992
- function normalizeTurn(value) {
2993
- if (!value || typeof value !== "object" || Array.isArray(value)) return value;
2994
- return {
2995
- error: null,
2996
- startedAt: null,
2997
- completedAt: null,
2998
- durationMs: null,
2999
- ...value,
3000
- items: Array.isArray(value.items) ? value.items.map(normalizeThreadItem) : []
3001
- };
3002
- }
3003
- function normalizeThreadItem(value) {
3004
- if (!value || typeof value !== "object" || Array.isArray(value)) return value;
3005
- switch (value.type) {
3006
- case "agentMessage": return {
3007
- phase: null,
3008
- delivery: null,
3009
- memoryCitation: null,
3010
- ...value
3011
- };
3012
- case "plan": return {
3013
- text: "",
3014
- ...value
3015
- };
3016
- case "reasoning": return {
3017
- summary: [],
3018
- content: [],
3019
- ...value
3020
- };
3021
- case "dynamicToolCall": return {
3022
- namespace: null,
3023
- arguments: null,
3024
- status: "completed",
3025
- contentItems: null,
3026
- success: null,
3027
- durationMs: null,
3028
- ...value
3029
- };
3030
- default: return value;
3031
- }
3032
- }
3033
- function normalizeTurnEnvelope(value) {
3034
- if (!value || typeof value !== "object" || Array.isArray(value) || !("turn" in value)) return value;
3035
- return {
3036
- ...value,
3037
- turn: normalizeTurn(value.turn)
3038
- };
3242
+ const normalized = normalizeWithDefaults(validate.schema, value);
3243
+ return validate.check(normalized) ? normalized : void 0;
3039
3244
  }
3040
3245
  function formatValidationErrors(validate, value) {
3041
3246
  const errors = validate.errors(value);
@@ -3046,356 +3251,141 @@ function formatValidationErrors(validate, value) {
3046
3251
  }).join("; ");
3047
3252
  }
3048
3253
  //#endregion
3049
- //#region extensions/codex/src/app-server/request-attempt.ts
3050
- /** One wire attempt; local waiter expiry need not imply a native response. */
3051
- function createCodexRequestAttempt(params) {
3052
- let pending = true;
3053
- let mayHaveWritten = false;
3054
- const waiters = /* @__PURE__ */ new Set();
3055
- const diagnostics = params.diagnosticIdentity ? {
3056
- ...params.diagnosticIdentity,
3057
- waiterOrdinal: 0,
3058
- attemptCreatedAtMs: performance.now(),
3059
- firstPossibleWriteAtMs: null,
3060
- wireOutcomeAtWaiterSettlement: "retained-pending",
3061
- wireObservedAtMs: null
3062
- } : void 0;
3063
- const finish = (outcome) => {
3064
- if (!pending) return false;
3065
- pending = false;
3066
- if (diagnostics) {
3067
- diagnostics.wireOutcomeAtWaiterSettlement = outcome;
3068
- diagnostics.wireObservedAtMs = performance.now();
3254
+ //#region extensions/codex/src/app-server/server-requests.ts
3255
+ var CodexServerRequestResolvedError = class extends Error {
3256
+ constructor() {
3257
+ super("Codex server request resolved by another client");
3258
+ this.name = "CodexServerRequestResolvedError";
3259
+ }
3260
+ };
3261
+ /** Physical-client owner for inbound requests, cancellation, and response deadlines. */
3262
+ var CodexServerRequests = class {
3263
+ constructor(respond) {
3264
+ this.respond = respond;
3265
+ this.handlers = /* @__PURE__ */ new Set();
3266
+ this.refreshWork = new AsyncWorkScope();
3267
+ this.closed = false;
3268
+ this.active = /* @__PURE__ */ new Map();
3269
+ }
3270
+ resolve(params) {
3271
+ if (!isJsonObject(params) || typeof params.threadId !== "string") return;
3272
+ const id = params.requestId;
3273
+ if (typeof id !== "string" && typeof id !== "number") return;
3274
+ const request = this.active.get(id);
3275
+ if (request?.threadId === params.threadId) {
3276
+ this.active.delete(id);
3277
+ request.controller.abort(new CodexServerRequestResolvedError());
3069
3278
  }
3070
- params.onSettled();
3071
- return true;
3072
- };
3073
- const rejectWaiters = (error, outcome) => {
3074
- for (const waiter of waiters) waiter.reject(error, outcome);
3075
- };
3076
- const currentWaiterError = (waiter) => {
3077
- if (!params.retainWritten) return;
3078
- if (waiter.signal?.aborted) return {
3079
- error: params.cancellationError("aborted", mayHaveWritten, waiter.signal.reason),
3080
- outcome: "aborted"
3279
+ }
3280
+ close(error) {
3281
+ this.closed = true;
3282
+ this.closing ??= this.refreshWork.drain();
3283
+ const requests = [...this.active.values()];
3284
+ this.active.clear();
3285
+ for (const request of requests) request.controller.abort(error);
3286
+ return this.closing;
3287
+ }
3288
+ async handle(request) {
3289
+ if (this.closed) return;
3290
+ const controller = new AbortController();
3291
+ const entry = {
3292
+ threadId: isJsonObject(request.params) ? request.params.threadId : void 0,
3293
+ controller
3081
3294
  };
3082
- if (waiter.deadline !== void 0 && performance.now() >= waiter.deadline) return {
3083
- error: params.cancellationError("timed out", mayHaveWritten),
3084
- outcome: "timed-out"
3295
+ this.active.set(request.id, entry);
3296
+ const deadline = createDeferred();
3297
+ const onAbort = () => deadline.resolve(void 0);
3298
+ controller.signal.addEventListener("abort", onAbort, { once: true });
3299
+ let timeout;
3300
+ let timeoutMs = resolveDynamicToolServerRequestTimeoutMs(readCodexDynamicToolCallParams(request.params));
3301
+ let settled = false;
3302
+ let executionTimeoutResolved = false;
3303
+ const armTimeout = () => {
3304
+ clearTimeout(timeout);
3305
+ timeout = setTimeout(() => {
3306
+ embeddedAgentLog.warn("codex app-server server request timed out", {
3307
+ id: request.id,
3308
+ method: request.method,
3309
+ timeoutMs
3310
+ });
3311
+ deadline.resolve(timeoutServerRequestResponse(timeoutMs));
3312
+ controller.abort(/* @__PURE__ */ new Error("codex app-server server request timed out"));
3313
+ }, timeoutMs);
3314
+ timeout.unref?.();
3085
3315
  };
3086
- try {
3087
- waiter.assertCurrent?.();
3088
- } catch (error) {
3089
- return {
3090
- error: toStringifiedError(error),
3091
- outcome: "authority-rejected"
3092
- };
3093
- }
3094
- if (waiter.signal?.aborted) return {
3095
- error: params.cancellationError("aborted", mayHaveWritten, waiter.signal.reason),
3096
- outcome: "aborted"
3316
+ const setExecutionTimeoutMs = (executionTimeoutMs) => {
3317
+ if (settled || controller.signal.aborted || executionTimeoutResolved || !Number.isFinite(executionTimeoutMs) || executionTimeoutMs <= 0) return;
3318
+ executionTimeoutResolved = true;
3319
+ timeoutMs = addSafeTimeoutDelayGraceMs(executionTimeoutMs, 3e4);
3320
+ armTimeout();
3097
3321
  };
3098
- if (waiter.deadline !== void 0 && performance.now() >= waiter.deadline) return {
3099
- error: params.cancellationError("timed out", mayHaveWritten),
3100
- outcome: "timed-out"
3322
+ const dynamicTool = request.method === "item/tool/call";
3323
+ if (dynamicTool) armTimeout();
3324
+ const run = async () => {
3325
+ for (const handler of this.handlers) {
3326
+ if (controller.signal.aborted) return;
3327
+ const result = await handler(request, controller.signal, dynamicTool ? setExecutionTimeoutMs : void 0);
3328
+ if (result !== void 0) return result;
3329
+ }
3101
3330
  };
3102
- };
3103
- return {
3104
- method: params.method,
3105
- get pending() {
3106
- return pending;
3107
- },
3108
- wait(options, deadline) {
3109
- const { timeoutMs, signal, assertCurrent, disposition, overloadAttemptOrdinal } = options;
3110
- let observe = options.attemptWaiterFinished;
3111
- return new Promise((resolve, reject) => {
3112
- if (!pending) {
3113
- reject(/* @__PURE__ */ new Error("Codex request attempt is already settled"));
3114
- return;
3115
- }
3116
- let timer;
3117
- let removeAbort;
3118
- const waiterOrdinal = diagnostics ? ++diagnostics.waiterOrdinal : 0;
3119
- const waiterAttachedAtMs = diagnostics && observe ? performance.now() : 0;
3120
- const cleanup = () => {
3121
- clearTimeout(timer);
3122
- timer = void 0;
3123
- removeAbort?.();
3124
- removeAbort = void 0;
3125
- };
3126
- const detach = (waiterOutcome) => {
3127
- if (!waiters.delete(waiter)) return false;
3128
- cleanup();
3129
- if (waiters.size === 0 && (!params.retainWritten || !mayHaveWritten)) finish(mayHaveWritten ? "correlation-closed" : "not-written");
3130
- const callback = observe;
3131
- observe = void 0;
3132
- if (diagnostics && callback) try {
3133
- callback({
3134
- ...diagnostics,
3135
- waiterOrdinal,
3136
- disposition,
3137
- overloadAttemptOrdinal,
3138
- waiterAttachedAtMs,
3139
- waiterSettledAtMs: performance.now(),
3140
- waiterOutcome
3141
- });
3142
- } catch {}
3143
- return true;
3144
- };
3145
- const waiter = {
3146
- resolve: (value) => {
3147
- if (!detach("resolved")) return;
3148
- resolve(value);
3149
- },
3150
- reject: (error, outcome) => {
3151
- if (detach(outcome)) reject(error);
3152
- },
3153
- cleanup,
3154
- signal,
3155
- ...params.retainWritten ? {
3156
- deadline,
3157
- assertCurrent
3158
- } : {}
3159
- };
3160
- waiters.add(waiter);
3161
- if (params.retainWritten && deadline !== void 0 && performance.now() >= deadline) {
3162
- waiter.reject(params.cancellationError("timed out", mayHaveWritten), "timed-out");
3163
- return;
3164
- }
3165
- if (timeoutMs && Number.isFinite(timeoutMs) && timeoutMs > 0) {
3166
- const remaining = params.retainWritten && deadline !== void 0 ? deadline - performance.now() : timeoutMs;
3167
- timer = setTimeout(() => waiter.reject(params.cancellationError("timed out", mayHaveWritten), "timed-out"), Math.max(params.retainWritten ? 1 : 100, remaining));
3168
- timer.unref?.();
3169
- }
3170
- if (signal) {
3171
- const abort = () => waiter.reject(params.cancellationError("aborted", mayHaveWritten, signal.reason), "aborted");
3172
- signal.addEventListener("abort", abort, { once: true });
3173
- removeAbort = () => signal.removeEventListener("abort", abort);
3174
- if (signal.aborted) abort();
3175
- }
3331
+ try {
3332
+ const work = request.method === "account/chatgptAuthTokens/refresh" ? this.refreshWork.track(run) : run();
3333
+ const result = await Promise.race([work, deadline.promise]);
3334
+ if (this.active.get(request.id) === entry) this.respond({
3335
+ id: request.id,
3336
+ result: result === void 0 ? defaultServerRequestResponse(request) : result
3176
3337
  });
3177
- },
3178
- resolve(value) {
3179
- if (!finish("native-ok")) return;
3180
- params.onResponse?.(mayHaveWritten);
3181
- for (const waiter of waiters) {
3182
- const error = currentWaiterError(waiter);
3183
- if (error) waiter.reject(error.error, error.outcome);
3184
- else waiter.resolve(value);
3185
- }
3186
- },
3187
- reject(error, definitelyNotEnqueued = false) {
3188
- if (finish(definitelyNotEnqueued ? "ingress-rejected" : "native-error")) {
3189
- if (definitelyNotEnqueued) mayHaveWritten = false;
3190
- params.onResponse?.(mayHaveWritten);
3191
- for (const waiter of waiters) {
3192
- const current = currentWaiterError(waiter);
3193
- waiter.reject(current?.error ?? params.localError(error, mayHaveWritten), current?.outcome ?? "native-error");
3194
- }
3195
- }
3196
- },
3197
- close(error) {
3198
- if (finish("correlation-closed")) rejectWaiters(params.localError(error, mayHaveWritten), "client-closed");
3199
- },
3200
- failLocal(error) {
3201
- if (!pending) return;
3202
- if (!params.retainWritten || !mayHaveWritten) finish(mayHaveWritten ? "correlation-closed" : "not-written");
3203
- rejectWaiters(params.localError(error, mayHaveWritten), "local-failed");
3204
- },
3205
- markWritten() {
3206
- mayHaveWritten = true;
3207
- if (diagnostics && diagnostics.firstPossibleWriteAtMs === null) diagnostics.firstPossibleWriteAtMs = performance.now();
3208
- },
3209
- cleanup() {
3210
- for (const waiter of waiters) waiter.cleanup();
3211
- }
3212
- };
3213
- }
3214
- //#endregion
3215
- //#region extensions/codex/src/app-server/transport-websocket.ts
3216
- /**
3217
- * Adapts a remote Codex app-server WebSocket endpoint to the shared stdio-like
3218
- * transport interface.
3219
- */
3220
- const WEBSOCKET_HANDSHAKE_TIMEOUT_MS = 1e4;
3221
- const WEBSOCKET_PING_INTERVAL_MS = 2e4;
3222
- const WEBSOCKET_PONG_TIMEOUT_MS = 2e4;
3223
- const MAX_CONSECUTIVE_MISSED_WEBSOCKET_PONGS = 5;
3224
- /** Opens a WebSocket app-server transport and maps newline-delimited frames to stdout/stdin. */
3225
- function createWebSocketTransport(options) {
3226
- if (!options.url) throw new Error("codex app-server websocket transport requires plugins.entries.codex.config.appServer.url");
3227
- const events = new EventEmitter();
3228
- const stdout = new PassThrough();
3229
- const stderr = new PassThrough();
3230
- const websocketOptions = {
3231
- headers: {
3232
- ...options.headers,
3233
- ...options.authToken ? { Authorization: `Bearer ${options.authToken}` } : {}
3234
- },
3235
- perMessageDeflate: false,
3236
- ...options.transport === "websocket" ? { handshakeTimeout: WEBSOCKET_HANDSHAKE_TIMEOUT_MS } : {}
3237
- };
3238
- const unixSocketPath = resolveCodexAppServerUnixSocketPath(options);
3239
- const socket = unixSocketPath ? new WebSocket("ws://localhost/", {
3240
- ...websocketOptions,
3241
- createConnection: () => connectCodexAppServerUnixSocket(unixSocketPath)
3242
- }) : new WebSocket(options.url, websocketOptions);
3243
- const pendingFrames = [];
3244
- const stdinDecoder = new StringDecoder("utf8");
3245
- let pendingLine = "";
3246
- let killed = false;
3247
- let exitCode = null;
3248
- let pingTimeout;
3249
- let pongTimeout;
3250
- let expectedPong;
3251
- let consecutiveMissedPongs = 0;
3252
- let heartbeatSequence = 0;
3253
- const clearConnectionHealthTimers = () => {
3254
- if (pingTimeout) {
3255
- clearTimeout(pingTimeout);
3256
- pingTimeout = void 0;
3257
- }
3258
- if (pongTimeout) {
3259
- clearTimeout(pongTimeout);
3260
- pongTimeout = void 0;
3261
- }
3262
- expectedPong = void 0;
3263
- };
3264
- const sendHeartbeatPing = () => {
3265
- if (socket.readyState !== WebSocket.OPEN || pongTimeout) return;
3266
- const payload = Buffer.from(`openclaw-codex-${++heartbeatSequence}`);
3267
- expectedPong = payload;
3268
- pongTimeout = setTimeout(() => {
3269
- pongTimeout = void 0;
3270
- expectedPong = void 0;
3271
- consecutiveMissedPongs += 1;
3272
- if (consecutiveMissedPongs >= MAX_CONSECUTIVE_MISSED_WEBSOCKET_PONGS) {
3273
- socket.terminate();
3274
- return;
3338
+ } catch (error) {
3339
+ if (this.active.get(request.id) === entry) {
3340
+ embeddedAgentLog.warn("codex app-server server request handler failed", {
3341
+ id: request.id,
3342
+ method: request.method,
3343
+ error
3344
+ });
3345
+ this.respond({
3346
+ id: request.id,
3347
+ error: {
3348
+ code: -32603,
3349
+ message: coerceErrorMessage(error)
3350
+ }
3351
+ });
3275
3352
  }
3276
- sendHeartbeatPing();
3277
- }, WEBSOCKET_PONG_TIMEOUT_MS);
3278
- pongTimeout.unref();
3279
- socket.ping(payload, void 0, (error) => {
3280
- if (error) socket.terminate();
3281
- });
3282
- };
3283
- const scheduleHeartbeatPing = () => {
3284
- if (options.transport !== "websocket" || socket.readyState !== WebSocket.OPEN || pingTimeout || pongTimeout) return;
3285
- pingTimeout = setTimeout(() => {
3286
- pingTimeout = void 0;
3287
- sendHeartbeatPing();
3288
- }, WEBSOCKET_PING_INTERVAL_MS);
3289
- pingTimeout.unref();
3290
- };
3291
- const recordConnectionActivity = () => {
3292
- consecutiveMissedPongs = 0;
3293
- if (pongTimeout) {
3294
- clearTimeout(pongTimeout);
3295
- pongTimeout = void 0;
3296
- }
3297
- expectedPong = void 0;
3298
- scheduleHeartbeatPing();
3299
- };
3300
- const sendFrame = (frame) => {
3301
- const trimmed = frame.trim();
3302
- if (!trimmed) return;
3303
- if (socket.readyState === WebSocket.OPEN) {
3304
- socket.send(trimmed);
3305
- return;
3353
+ } finally {
3354
+ settled = true;
3355
+ clearTimeout(timeout);
3356
+ controller.signal.removeEventListener("abort", onAbort);
3357
+ if (this.active.get(request.id) === entry) this.active.delete(request.id);
3306
3358
  }
3307
- pendingFrames.push(trimmed);
3359
+ }
3360
+ };
3361
+ function defaultServerRequestResponse(request) {
3362
+ if (request.method === "item/tool/call") return {
3363
+ contentItems: [{
3364
+ type: "inputText",
3365
+ text: "OpenClaw did not register a handler for this app-server tool call."
3366
+ }],
3367
+ success: false
3308
3368
  };
3309
- socket.once("open", () => {
3310
- for (const frame of pendingFrames.splice(0)) socket.send(frame);
3311
- scheduleHeartbeatPing();
3312
- });
3313
- socket.on("pong", (payload) => {
3314
- if (expectedPong?.equals(payload)) recordConnectionActivity();
3315
- });
3316
- socket.once("error", (error) => {
3317
- clearConnectionHealthTimers();
3318
- events.emit("error", error);
3319
- });
3320
- socket.once("close", (code, reason) => {
3321
- clearConnectionHealthTimers();
3322
- killed = true;
3323
- exitCode = code;
3324
- events.emit("exit", code, reason.toString("utf8"));
3325
- });
3326
- socket.on("message", (data) => {
3327
- if (options.transport === "websocket") recordConnectionActivity();
3328
- const text = websocketFrameToText(data);
3329
- stdout.write(text.endsWith("\n") ? text : `${text}\n`);
3330
- });
3331
- const stdin = new Writable({
3332
- write(chunk, _encoding, callback) {
3333
- pendingLine += stdinDecoder.write(chunk);
3334
- const lines = pendingLine.split("\n");
3335
- pendingLine = lines.pop() ?? "";
3336
- for (const frame of lines) sendFrame(frame);
3337
- callback();
3338
- },
3339
- final(callback) {
3340
- pendingLine += stdinDecoder.end();
3341
- if (pendingLine) sendFrame(pendingLine);
3342
- pendingLine = "";
3343
- callback();
3344
- }
3345
- });
3346
- const closeSocket = () => {
3347
- if (socket.readyState === WebSocket.CLOSED || socket.readyState === WebSocket.CLOSING) return;
3348
- socket.close();
3369
+ if (request.method === "item/commandExecution/requestApproval" || request.method === "item/fileChange/requestApproval") return { decision: "decline" };
3370
+ if (request.method === "item/permissions/requestApproval") return {
3371
+ permissions: {},
3372
+ scope: "turn"
3349
3373
  };
3350
- stdin.once("finish", closeSocket);
3351
- stdin.once("close", closeSocket);
3374
+ if (request.method === "item/tool/requestUserInput") return { answers: {} };
3375
+ if (request.method === "mcpServer/elicitation/request") return createCodexElicitationResponse("decline", null, { message: "OpenClaw has no interactive handler for this elicitation." });
3376
+ return {};
3377
+ }
3378
+ function timeoutServerRequestResponse(timeoutMs) {
3352
3379
  return {
3353
- maxFrameBytes: 16777216,
3354
- stdin,
3355
- stdout,
3356
- stderr,
3357
- get killed() {
3358
- return killed;
3359
- },
3360
- get exitCode() {
3361
- return exitCode;
3362
- },
3363
- kill: (signal) => {
3364
- killed = true;
3365
- clearConnectionHealthTimers();
3366
- if (signal === "SIGKILL") socket.terminate();
3367
- else socket.close();
3368
- },
3369
- once: (event, listener) => events.once(event, listener),
3370
- off: (event, listener) => events.off(event, listener)
3380
+ contentItems: [{
3381
+ type: "inputText",
3382
+ text: `OpenClaw dynamic tool call timed out after ${timeoutMs}ms before sending a response to Codex.`
3383
+ }],
3384
+ success: false
3371
3385
  };
3372
3386
  }
3373
- /** Opens the owner-scoped Codex control socket used by the WebSocket upgrade. */
3374
- function connectCodexAppServerUnixSocket(socketPath) {
3375
- return net.createConnection(socketPath);
3376
- }
3377
- /** Resolves the canonical or explicitly configured Codex control socket. */
3378
- function resolveCodexAppServerUnixSocketPath(options) {
3379
- if (options.transport !== "unix") {
3380
- if (options.url?.startsWith("unix://")) throw new Error("codex app-server unix URL requires unix transport");
3381
- return;
3382
- }
3383
- const url = options.url ?? "unix://";
3384
- if (!url.startsWith("unix://")) throw new Error("codex app-server unix transport requires a unix:// URL");
3385
- return url.slice(7) || path.join(resolveCodexAppServerUserHomeDir(options.env ?? process.env), "app-server-control", "app-server-control.sock");
3386
- }
3387
- function websocketFrameToText(data) {
3388
- if (typeof data === "string") return data;
3389
- if (Buffer.isBuffer(data)) return data.toString("utf8");
3390
- if (Array.isArray(data)) return Buffer.concat(data).toString("utf8");
3391
- return Buffer.from(data).toString("utf8");
3392
- }
3393
3387
  //#endregion
3394
3388
  //#region extensions/codex/src/app-server/client.ts
3395
- /**
3396
- * JSON-RPC client for Codex app-server transports, including request/response
3397
- * routing, notification fanout, server request handlers, and version checks.
3398
- */
3399
3389
  var client_exports = /* @__PURE__ */ __exportAll({
3400
3390
  CodexAppServerClient: () => CodexAppServerClient,
3401
3391
  getCodexAppServerClientInstanceId: () => getCodexAppServerClientInstanceId,
@@ -3410,15 +3400,11 @@ var client_exports = /* @__PURE__ */ __exportAll({
3410
3400
  isUnsupportedCodexAppServerVersionError: () => isUnsupportedCodexAppServerVersionError,
3411
3401
  resolveCodexAppServerClientInstanceId: () => resolveCodexAppServerClientInstanceId
3412
3402
  });
3413
- const CODEX_APP_SERVER_PARSE_LOG_MAX = 500;
3414
- const CODEX_APP_SERVER_PARSE_BUFFER_MAX = 8388608;
3415
- const CODEX_APP_SERVER_PARSE_BUFFER_MAX_LINES = 1e3;
3416
3403
  const CODEX_APP_SERVER_STDERR_TAIL_MAX = 2e3;
3417
3404
  const CODEX_APP_SERVER_OVERLOAD_MAX_RETRIES = 3;
3418
3405
  const CODEX_APP_SERVER_OVERLOAD_RETRY_BASE_MS = 50;
3419
3406
  const CODEX_APP_SERVER_PENDING_STARTUP_WARNINGS_MAX = 32;
3420
3407
  const CODEX_APP_SERVER_CLIENT_INSTANCE_IDS = /* @__PURE__ */ new WeakMap();
3421
- const UNPAIRED_SURROGATE_RE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g;
3422
3408
  /** Process-local generation fence for bindings tied to one app-server client instance. */
3423
3409
  function getCodexAppServerClientInstanceId(client) {
3424
3410
  const current = CODEX_APP_SERVER_CLIENT_INSTANCE_IDS.get(client);
@@ -3477,19 +3463,19 @@ function isCodexAppServerPrewriteRequestCancellationError(error) {
3477
3463
  function isCodexAppServerIndeterminateTransportError(error) {
3478
3464
  return error instanceof Error && "code" in error && error.code === "CODEX_APP_SERVER_REQUEST_TRANSPORT_INDETERMINATE" && "mayHaveWritten" in error && error.mayHaveWritten === true;
3479
3465
  }
3480
- /** Returns true for errors that mean the app-server transport is closed. */
3481
3466
  function isCodexAppServerConnectionClosedError(error) {
3482
3467
  if (!(error instanceof Error)) return false;
3483
3468
  if (isCodexAppServerIndeterminateTransportError(error)) return true;
3484
3469
  return error.message === "codex app-server client is closed" || error.message.startsWith("codex app-server exited:");
3485
3470
  }
3486
- /** Stateful app-server JSON-RPC client over stdio or websocket transport. */
3487
3471
  var CodexAppServerClient = class CodexAppServerClient {
3488
3472
  constructor(child) {
3489
3473
  this.instanceId = randomUUID();
3474
+ this.decoder = new CodexAppServerMessageDecoder(logCodexAppServerParseFailure);
3475
+ this.catalogWorker = new CodexCatalogWorker();
3490
3476
  this.pending = /* @__PURE__ */ new Map();
3491
3477
  this.catalogResponses = /* @__PURE__ */ new WeakMap();
3492
- this.requestHandlers = /* @__PURE__ */ new Set();
3478
+ this.serverRequests = new CodexServerRequests((response) => this.writeMessage(response));
3493
3479
  this.notificationHandlers = /* @__PURE__ */ new Set();
3494
3480
  this.pendingStartupWarnings = [];
3495
3481
  this.closeHandlers = /* @__PURE__ */ new Set();
@@ -3503,28 +3489,24 @@ var CodexAppServerClient = class CodexAppServerClient {
3503
3489
  this.privateTransportSecrets = /* @__PURE__ */ new Set();
3504
3490
  this.privateStderrPending = "";
3505
3491
  this.child = child;
3506
- this.lines = createInterface({ input: child.stdout });
3507
- this.lines.on("line", (line) => this.handleLine(line));
3508
- this.lines.on("error", (error) => this.closeWithError(toStringifiedError(error)));
3492
+ this.closeMessageReader = listenCodexAppServerLines(child.stdout, (line) => {
3493
+ const route = this.catalogWorker.continuation ?? (this.decoder.hasPending ? void 0 : readCodexCatalogDecodeRoute(line));
3494
+ if (route) return this.decodeCatalogLine(line, route);
3495
+ return this.handleParsedMessage(this.decoder.parse(line.toString("utf8")));
3496
+ }, (error) => this.closeWithError(toStringifiedError(error)));
3509
3497
  child.stdout.on("error", (error) => this.closeWithError(toStringifiedError(error)));
3510
- child.stderr.setEncoding("utf8");
3511
- child.stderr.on("data", (chunk) => {
3498
+ observeCodexAppServerStderr(child.stderr, (chunk) => {
3512
3499
  const text = this.redactPrivateStderr(chunk);
3513
3500
  this.stderrTail = appendBoundedTail(this.stderrTail, text, CODEX_APP_SERVER_STDERR_TAIL_MAX);
3514
- const trimmed = text.trim();
3515
- if (trimmed) embeddedAgentLog.debug(`codex app-server stderr: ${trimmed}`);
3516
- });
3517
- child.stderr.on("error", (error) => {
3518
- embeddedAgentLog.warn("codex app-server stderr stream failed", { error });
3501
+ return text;
3519
3502
  });
3520
3503
  child.once("error", (error) => this.closeWithError(toStringifiedError(error)));
3521
3504
  child.once("exit", (code, signal) => {
3522
3505
  this.transportExited = true;
3523
- this.closeWithError(buildCodexAppServerExitError(code, signal, this.stderrTail));
3506
+ this.closeWithError(child.startupFailure?.error ?? buildCodexAppServerExitError(code, signal, this.stderrTail));
3524
3507
  });
3525
3508
  child.stdin.on?.("error", (error) => this.closeWithError(toStringifiedError(error)));
3526
3509
  }
3527
- /** Starts a new app-server client using resolved runtime start options. */
3528
3510
  static async start(options, assertCurrent) {
3529
3511
  const defaults = resolveCodexAppServerRuntimeOptions().start;
3530
3512
  const startOptions = {
@@ -3542,43 +3524,26 @@ var CodexAppServerClient = class CodexAppServerClient {
3542
3524
  return client;
3543
3525
  } catch (error) {
3544
3526
  assertCurrent?.();
3545
- if (client?.transportExited && hasCodexAppServerNaturalExit(client.child)) throw buildCodexAppServerExitError(client.child.exitCode, client.child.signalCode, client.stderrTail);
3527
+ if (client?.transportExited && hasCodexAppServerNaturalExit(client.child)) throw client.child.startupFailure?.error ?? buildCodexAppServerExitError(client.child.exitCode, client.child.signalCode, client.stderrTail);
3546
3528
  const stderr = client?.getStderrDiagnostic();
3547
3529
  throw stderr ? new Error(`${coerceErrorMessage(error)}; stderr=${JSON.stringify(stderr)}`, { cause: error }) : error;
3548
3530
  }
3549
3531
  }
3550
- /** Builds a client around a fake transport for tests. */
3551
3532
  static fromTransportForTests(child) {
3552
3533
  return new CodexAppServerClient(child);
3553
3534
  }
3554
- /** Performs the app-server initialize handshake and validates protocol version. */
3555
3535
  async initialize() {
3556
3536
  if (this.initialized) return;
3557
- const response = await this.request("initialize", {
3558
- clientInfo: {
3559
- name: "openclaw",
3560
- title: "OpenClaw",
3561
- version: OPENCLAW_VERSION
3562
- },
3563
- capabilities: {
3564
- experimentalApi: true,
3565
- extensions: {
3566
- "openai/standard-form-input": {},
3567
- "openai/form": {},
3568
- "io.modelcontextprotocol/ui": { mimeTypes: ["text/html;profile=mcp-app"] }
3569
- }
3570
- }
3571
- });
3572
- this.serverVersion = assertSupportedCodexAppServerVersion(response);
3573
- this.runtimeIdentity = buildCodexAppServerRuntimeIdentity(response, this.serverVersion);
3537
+ const response = await this.request("initialize", buildCodexAppServerInitializeParams());
3538
+ this.child.startupFailure?.complete();
3539
+ const serverVersion = assertSupportedCodexAppServerVersion(response);
3540
+ this.runtimeIdentity = buildCodexAppServerRuntimeIdentity(response, serverVersion);
3574
3541
  this.notify("initialized");
3575
3542
  this.initialized = true;
3576
3543
  }
3577
- /** Returns the version detected during initialize. */
3578
3544
  getServerVersion() {
3579
- return this.serverVersion;
3545
+ return this.runtimeIdentity?.serverVersion;
3580
3546
  }
3581
- /** Returns runtime metadata detected during initialize. */
3582
3547
  getRuntimeIdentity() {
3583
3548
  return this.runtimeIdentity ? { ...this.runtimeIdentity } : void 0;
3584
3549
  }
@@ -3717,7 +3682,7 @@ var CodexAppServerClient = class CodexAppServerClient {
3717
3682
  requestOnce(method, params, options, overloadAttemptOrdinal, onWriteStateChange, deadline, onResponse) {
3718
3683
  if (this.closed) return Promise.reject(this.closeError ?? /* @__PURE__ */ new Error("codex app-server client is closed"));
3719
3684
  if (options.signal?.aborted) return Promise.reject(new CodexAppServerLocalRequestCancellationError(method, "aborted", false, options.signal?.reason));
3720
- const id = this.nextId++;
3685
+ const id = codexCatalogRequestId(method, params, this.nextId++, options.catalogPreview);
3721
3686
  if (method === "account/login/start" || method === "account/logout" || method === "config/value/write" || method === "config/batchWrite") this.modelCatalogRevision += 1;
3722
3687
  const message = {
3723
3688
  id,
@@ -3742,14 +3707,12 @@ var CodexAppServerClient = class CodexAppServerClient {
3742
3707
  localError: (error, written) => written && !(error instanceof CodexAppServerRpcError) && !isCodexAppServerIndeterminateRequestCancellationError(error) && !isCodexAppServerIndeterminateTransportError(error) ? new CodexAppServerIndeterminateTransportError(method, error) : error
3743
3708
  });
3744
3709
  this.pending.set(id, attempt);
3745
- if (options.catalogPreview && method === "thread/list") this.catalogResponses.set(attempt, {
3710
+ if (options.catalogPreview) this.catalogResponses.set(attempt, {
3746
3711
  preview: options.catalogPreviewCache,
3747
3712
  remainingRows: options.catalogRows
3748
3713
  });
3749
3714
  const result = attempt.wait({
3750
3715
  ...options,
3751
- assertCurrent: void 0,
3752
- disposition: "new",
3753
3716
  overloadAttemptOrdinal
3754
3717
  }, deadline);
3755
3718
  if (!attempt.pending) return result;
@@ -3764,25 +3727,21 @@ var CodexAppServerClient = class CodexAppServerClient {
3764
3727
  }
3765
3728
  return result;
3766
3729
  }
3767
- /** Sends a fire-and-forget JSON-RPC notification to the app-server. */
3768
3730
  notify(method, params) {
3769
3731
  this.writeMessage({
3770
3732
  method,
3771
3733
  params
3772
3734
  });
3773
3735
  }
3774
- /** Registers a handler for app-server requests sent back to OpenClaw. */
3775
3736
  addRequestHandler(handler) {
3776
- this.requestHandlers.add(handler);
3777
- return () => this.requestHandlers.delete(handler);
3737
+ this.serverRequests.handlers.add(handler);
3738
+ return () => this.serverRequests.handlers.delete(handler);
3778
3739
  }
3779
- /** Registers a notification handler and returns its disposer. */
3780
3740
  addNotificationHandler(handler) {
3781
3741
  this.notificationHandlers.add(handler);
3782
3742
  for (const notification of this.pendingStartupWarnings.splice(0)) this.handleNotification(notification);
3783
3743
  return () => this.notificationHandlers.delete(handler);
3784
3744
  }
3785
- /** Registers a close handler and returns its disposer. */
3786
3745
  addCloseHandler(handler) {
3787
3746
  this.closeHandlers.add(handler);
3788
3747
  return () => this.closeHandlers.delete(handler);
@@ -3797,33 +3756,26 @@ var CodexAppServerClient = class CodexAppServerClient {
3797
3756
  this.child.once("exit", onExit);
3798
3757
  return () => this.child.off?.("exit", onExit);
3799
3758
  }
3800
- /** Closes the transport without waiting for process/socket shutdown. */
3801
3759
  close() {
3802
- if (!this.markClosed(/* @__PURE__ */ new Error("codex app-server client is closed"))) return;
3803
- closeCodexAppServerTransport(this.child);
3760
+ this.closeWithError(/* @__PURE__ */ new Error("codex app-server client is closed"));
3804
3761
  }
3805
- /** Closes the transport and waits for shutdown according to transport policy. */
3806
3762
  async closeAndWait(options) {
3807
3763
  this.markClosed(/* @__PURE__ */ new Error("codex app-server client is closed"));
3808
- const result = await closeCodexAppServerTransportAndWait(this.child, options);
3764
+ const [result] = await Promise.all([closeCodexAppServerTransportAndWait(this.child, options), this.waitForCloseWork()]);
3809
3765
  return this.nativeExecutionObserved ? {
3810
3766
  ...result,
3811
3767
  cleanup: "uncertain"
3812
3768
  } : result;
3813
3769
  }
3770
+ /** Joins local settlement already started by close without changing transport policy. */
3771
+ async waitForCloseWork() {
3772
+ await this.serverRequestsClosed;
3773
+ await this.catalogWorkerClosed;
3774
+ }
3814
3775
  /** Closes this transport and runs cleanup only after physical process exit. */
3815
3776
  async closeAndRunAfterExit(onExit, operation) {
3816
- let settled = false;
3817
- const runOnExit = () => {
3818
- if (settled) return;
3819
- settled = true;
3820
- onExit();
3821
- };
3822
- if (this.transportExited) {
3823
- runOnExit();
3824
- return;
3825
- }
3826
- this.child.once("exit", runOnExit);
3777
+ this.addTransportExitHandler(onExit);
3778
+ if (this.transportExited) return;
3827
3779
  try {
3828
3780
  await this.closeAndWait();
3829
3781
  } catch (closeError) {
@@ -3871,65 +3823,16 @@ var CodexAppServerClient = class CodexAppServerClient {
3871
3823
  this.privateStderrPending = held ? text.slice(-held) : "";
3872
3824
  return held ? text.slice(0, -held) : text;
3873
3825
  }
3874
- handleLine(line) {
3875
- const rawLine = line.endsWith("\r") ? line.slice(0, -1) : line;
3876
- if (this.pendingParse) {
3877
- this.handlePendingParseLine(rawLine);
3878
- return;
3879
- }
3880
- const trimmed = rawLine.trim();
3881
- if (!trimmed) return;
3882
- let parsed;
3883
- try {
3884
- parsed = JSON.parse(trimmed);
3885
- } catch (error) {
3886
- if (shouldBufferCodexAppServerParseFailure(trimmed, error)) {
3887
- this.pendingParse = {
3888
- text: trimmed,
3889
- lineCount: 1,
3890
- firstError: error
3891
- };
3892
- return;
3893
- }
3894
- logCodexAppServerParseFailure(trimmed, error, 1);
3895
- return;
3896
- }
3897
- this.handleParsedMessage(parsed);
3898
- }
3899
- handlePendingParseLine(line) {
3900
- const pending = this.pendingParse;
3901
- if (!pending) return;
3902
- const candidate = `${pending.text}\\n${line}`;
3903
- let parsed;
3904
- try {
3905
- parsed = JSON.parse(candidate);
3906
- } catch (error) {
3907
- const lineCount = pending.lineCount + 1;
3908
- if (shouldBufferCodexAppServerParseFailure(candidate.trim(), error) && candidate.length <= CODEX_APP_SERVER_PARSE_BUFFER_MAX && lineCount <= CODEX_APP_SERVER_PARSE_BUFFER_MAX_LINES) {
3909
- this.pendingParse = {
3910
- text: candidate,
3911
- lineCount,
3912
- firstError: pending.firstError
3913
- };
3914
- return;
3915
- }
3916
- this.pendingParse = void 0;
3917
- logCodexAppServerParseFailure(candidate, error, lineCount);
3918
- return;
3919
- }
3920
- this.pendingParse = void 0;
3921
- this.handleParsedMessage(parsed);
3922
- }
3923
- handleParsedMessage(parsed) {
3924
- if (!parsed || typeof parsed !== "object") return;
3826
+ handleParsedMessage(parsed, previewStates) {
3827
+ if (this.closed || !parsed || typeof parsed !== "object") return;
3925
3828
  const message = parsed;
3926
3829
  if (isRpcResponse(message)) {
3927
- this.handleResponse(message);
3830
+ this.handleResponse(message, previewStates);
3928
3831
  return;
3929
3832
  }
3930
3833
  if (!("method" in message)) return;
3931
3834
  if ("id" in message && message.id !== void 0) {
3932
- this.handleServerRequest({
3835
+ this.serverRequests.handle({
3933
3836
  id: message.id,
3934
3837
  method: message.method,
3935
3838
  params: message.params
@@ -3941,83 +3844,19 @@ var CodexAppServerClient = class CodexAppServerClient {
3941
3844
  params: message.params
3942
3845
  });
3943
3846
  }
3944
- handleResponse(response) {
3945
- this.nativeExecutionObserved = dispatchCodexAppServerResponse(response, this.pending, this.catalogResponses, codexCatalogSourceForClient(this)) || this.nativeExecutionObserved;
3847
+ async decodeCatalogLine(line, route) {
3848
+ const decoded = await this.catalogWorker.decode(line, route, this.pending, this.catalogResponses);
3849
+ if (!decoded || this.closed) return;
3850
+ for (const failure of decoded.failures) logCodexAppServerParseFailure(failure.value, failure.error, failure.fragmentCount);
3851
+ if (decoded.projectionError) this.pending.get(decoded.projectionError.id)?.reject(decoded.projectionError.error, false);
3852
+ else if (decoded.message) this.handleParsedMessage(decoded.message, decoded.previewStates);
3946
3853
  }
3947
- async handleServerRequest(request) {
3948
- try {
3949
- const result = await this.runServerRequestHandlers(request);
3950
- if (result !== void 0) {
3951
- this.writeMessage({
3952
- id: request.id,
3953
- result
3954
- });
3955
- return;
3956
- }
3957
- this.writeMessage({
3958
- id: request.id,
3959
- result: defaultServerRequestResponse(request)
3960
- });
3961
- } catch (error) {
3962
- const message = coerceErrorMessage(error);
3963
- embeddedAgentLog.warn("codex app-server server request handler failed", {
3964
- id: request.id,
3965
- method: request.method,
3966
- error
3967
- });
3968
- this.writeMessage({
3969
- id: request.id,
3970
- error: {
3971
- code: -32603,
3972
- message
3973
- }
3974
- });
3975
- }
3976
- }
3977
- async runServerRequestHandlers(request) {
3978
- const controller = new AbortController();
3979
- if (request.method !== "item/tool/call") return await this.runServerRequestHandlersWithoutTimeout(request, controller.signal);
3980
- let timeoutMs = resolveDynamicToolServerRequestTimeoutMs(readCodexDynamicToolCallParams(request.params));
3981
- const deadline = createDeferred();
3982
- let timeout;
3983
- let settled = false;
3984
- let executionTimeoutResolved = false;
3985
- const armTimeout = () => {
3986
- clearTimeout(timeout);
3987
- timeout = setTimeout(() => {
3988
- embeddedAgentLog.warn("codex app-server server request timed out", {
3989
- id: request.id,
3990
- method: request.method,
3991
- timeoutMs
3992
- });
3993
- controller.abort(/* @__PURE__ */ new Error("codex app-server server request timed out"));
3994
- deadline.resolve(timeoutServerRequestResponse(timeoutMs));
3995
- }, timeoutMs);
3996
- timeout.unref?.();
3997
- };
3998
- const setExecutionTimeoutMs = (executionTimeoutMs) => {
3999
- if (settled || controller.signal.aborted || executionTimeoutResolved || !Number.isFinite(executionTimeoutMs) || executionTimeoutMs <= 0) return;
4000
- executionTimeoutResolved = true;
4001
- timeoutMs = addSafeTimeoutDelayGraceMs(executionTimeoutMs, 3e4);
4002
- armTimeout();
4003
- };
4004
- armTimeout();
4005
- try {
4006
- return await Promise.race([this.runServerRequestHandlersWithoutTimeout(request, controller.signal, setExecutionTimeoutMs), deadline.promise]);
4007
- } finally {
4008
- settled = true;
4009
- clearTimeout(timeout);
4010
- }
4011
- }
4012
- async runServerRequestHandlersWithoutTimeout(request, signal, setExecutionTimeoutMs) {
4013
- for (const handler of this.requestHandlers) {
4014
- if (signal.aborted) return;
4015
- const result = await handler(request, signal, setExecutionTimeoutMs);
4016
- if (result !== void 0) return result;
4017
- }
3854
+ handleResponse(response, previewStates) {
3855
+ this.nativeExecutionObserved = dispatchCodexAppServerResponse(response, this.pending, this.catalogResponses, codexCatalogSourceForClient(this), previewStates) || this.nativeExecutionObserved;
4018
3856
  }
4019
3857
  handleNotification(notification) {
4020
3858
  const params = notification.params;
3859
+ if (notification.method === "serverRequest/resolved") this.serverRequests.resolve(params);
4021
3860
  if (notification.method === "item/commandExecution/outputDelta" || notification.method === "item/commandExecution/terminalInteraction" || isJsonObject(params) && (isJsonObject(params.item) && params.item.type === "commandExecution" || isJsonObject(params.turn) && Array.isArray(params.turn.items) && params.turn.items.some((item) => isJsonObject(item) && item.type === "commandExecution"))) this.nativeExecutionObserved = true;
4022
3861
  if (notification.method === "account/updated") this.modelCatalogRevision += 1;
4023
3862
  if (this.notificationHandlers.size === 0 && notification.method === "configWarning") {
@@ -4041,15 +3880,18 @@ var CodexAppServerClient = class CodexAppServerClient {
4041
3880
  this.closed = true;
4042
3881
  closeCodexCatalogClientSource(this);
4043
3882
  this.closeError = error;
4044
- this.lines.close();
3883
+ this.closeMessageReader();
3884
+ this.decoder.clear();
3885
+ this.catalogWorkerClosed = this.catalogWorker.close(error);
3886
+ this.catalogWorkerClosed?.catch((closeError) => {
3887
+ embeddedAgentLog.warn("codex catalog worker shutdown failed", { error: closeError });
3888
+ });
3889
+ this.serverRequestsClosed = this.serverRequests.close(error);
4045
3890
  this.rejectPendingRequests(error);
4046
3891
  return true;
4047
3892
  }
4048
3893
  rejectPendingRequests(error) {
4049
- for (const pending of this.pending.values()) {
4050
- pending.cleanup();
4051
- pending.close(error);
4052
- }
3894
+ for (const pending of this.pending.values()) pending.close(error);
4053
3895
  this.pending.clear();
4054
3896
  for (const handler of this.closeHandlers) try {
4055
3897
  handler(this);
@@ -4058,36 +3900,6 @@ var CodexAppServerClient = class CodexAppServerClient {
4058
3900
  }
4059
3901
  }
4060
3902
  };
4061
- function defaultServerRequestResponse(request) {
4062
- if (request.method === "item/tool/call") return {
4063
- contentItems: [{
4064
- type: "inputText",
4065
- text: "OpenClaw did not register a handler for this app-server tool call."
4066
- }],
4067
- success: false
4068
- };
4069
- if (request.method === "item/commandExecution/requestApproval" || request.method === "item/fileChange/requestApproval") return { decision: "decline" };
4070
- if (request.method === "item/permissions/requestApproval") return {
4071
- permissions: {},
4072
- scope: "turn"
4073
- };
4074
- if (request.method === "item/tool/requestUserInput") return { answers: {} };
4075
- if (request.method === "mcpServer/elicitation/request") return createCodexElicitationResponse("decline", null, { message: "OpenClaw has no interactive handler for this elicitation." });
4076
- return {};
4077
- }
4078
- function stringifyCodexAppServerMessage(message) {
4079
- return JSON.stringify(message, (_key, value) => typeof value === "string" ? value.replace(UNPAIRED_SURROGATE_RE, "") : value) ?? "null";
4080
- }
4081
- function timeoutServerRequestResponse(timeoutMs) {
4082
- return {
4083
- contentItems: [{
4084
- type: "inputText",
4085
- text: `OpenClaw dynamic tool call timed out after ${timeoutMs}ms before sending a response to Codex.`
4086
- }],
4087
- success: false
4088
- };
4089
- }
4090
- /** Raised when the initialize handshake detects an unsupported app-server version. */
4091
3903
  var CodexAppServerVersionError = class extends Error {
4092
3904
  constructor(detectedVersion) {
4093
3905
  const detected = detectedVersion ? `detected ${detectedVersion}` : "OpenClaw could not determine the running Codex version";
@@ -4101,7 +3913,7 @@ function assertSupportedCodexAppServerVersion(response) {
4101
3913
  if (!detectedVersion) throw new CodexAppServerVersionError(detectedVersion);
4102
3914
  const detected = parse(detectedVersion);
4103
3915
  if (!detected || detected.compare("0.149.0") < 0) throw new CodexAppServerVersionError(detectedVersion);
4104
- if (detected.compare("0.154.0") > 0) embeddedAgentLog.warn("codex app-server is newer than OpenClaw's managed runtime; continuing with normal startup validation", {
3916
+ if (detected.compare("0.158.0") > 0) embeddedAgentLog.warn("codex app-server is newer than OpenClaw's managed runtime; continuing with normal startup validation", {
4105
3917
  detectedVersion,
4106
3918
  validatedVersion: CODEX_APP_SERVER_VERSION
4107
3919
  });
@@ -4110,65 +3922,16 @@ function assertSupportedCodexAppServerVersion(response) {
4110
3922
  function isUnsupportedCodexAppServerVersionError(error) {
4111
3923
  return error instanceof CodexAppServerVersionError;
4112
3924
  }
4113
- function buildCodexAppServerRuntimeIdentity(response, serverVersion) {
4114
- const userAgent = normalizeOptionalString(response.userAgent);
4115
- const codexHome = normalizeOptionalString(response.codexHome);
4116
- const platformFamily = normalizeOptionalString(response.platformFamily);
4117
- const platformOs = normalizeOptionalString(response.platformOs);
4118
- return {
4119
- serverVersion,
4120
- ...userAgent ? { userAgent } : {},
4121
- ...codexHome ? { codexHome } : {},
4122
- ...platformFamily ? { platformFamily } : {},
4123
- ...platformOs ? { platformOs } : {}
4124
- };
4125
- }
4126
- /** Extracts the Codex version from the app-server initialize user-agent field. */
4127
3925
  function readCodexVersionFromUserAgent(userAgent) {
4128
3926
  return (userAgent?.match(/^[^/]+\/(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?)(?:[\s(]|$)/))?.[1];
4129
3927
  }
4130
- function redactCodexAppServerLinePreview(value) {
4131
- const redacted = value.replace(/\s+/g, " ").trim().replace(/(Bearer\s+)[A-Za-z0-9._~+/-]+/gi, "$1<redacted>").replace(/("(?:api_?key|authorization|token|access_token|refresh_token)"\s*:\s*")([^"]+)(")/gi, "$1<redacted>$3").replace(/\b([a-z0-9_]*(?:api_?key|authorization|access_token|refresh_token|token))(\s*=\s*)(["']?)[^\s"']+(\3)/gi, "$1$2$3<redacted>$4");
4132
- return redacted.length > CODEX_APP_SERVER_PARSE_LOG_MAX ? `${truncateUtf16Safe(redacted, CODEX_APP_SERVER_PARSE_LOG_MAX)}...` : redacted;
4133
- }
4134
- function appendBoundedTail(current, next, maxLength) {
4135
- const combined = `${current}${next}`;
4136
- return combined.length > maxLength ? sliceUtf16Safe(combined, -maxLength) : combined;
4137
- }
4138
- function buildCodexAppServerExitError(code, signal, stderrTail) {
4139
- const stderrPreview = redactCodexAppServerLinePreview(stderrTail);
4140
- const suffix = stderrPreview ? ` stderr=${JSON.stringify(stderrPreview)}` : "";
4141
- return /* @__PURE__ */ new Error(`codex app-server exited: code=${formatExitValue(code)} signal=${formatExitValue(signal)}${suffix}`);
4142
- }
4143
- function shouldBufferCodexAppServerParseFailure(value, error) {
4144
- if (!value.startsWith("{") && !value.startsWith("[")) return false;
4145
- const message = coerceErrorMessage(error);
4146
- return message.includes("Unterminated string") || message.includes("Unexpected end of JSON input");
4147
- }
4148
- function logCodexAppServerParseFailure(value, error, fragmentCount) {
4149
- const linePreview = redactCodexAppServerLinePreview(value);
4150
- const suffix = fragmentCount > 1 ? ` fragments=${fragmentCount}` : "";
4151
- embeddedAgentLog.warn("failed to parse codex app-server message", {
4152
- error,
4153
- errorMessage: coerceErrorMessage(error),
4154
- fragmentCount,
4155
- linePreview,
4156
- consoleMessage: `failed to parse codex app-server message${suffix}: preview=${JSON.stringify(linePreview)}`
4157
- });
4158
- }
4159
3928
  const CODEX_APP_SERVER_APPROVAL_REQUEST_METHODS = /* @__PURE__ */ new Set([
4160
3929
  "item/commandExecution/requestApproval",
4161
3930
  "item/fileChange/requestApproval",
4162
3931
  "item/permissions/requestApproval"
4163
3932
  ]);
4164
- /** Returns true for app-server approval request methods OpenClaw can answer. */
4165
3933
  function isCodexAppServerApprovalRequest(method) {
4166
3934
  return CODEX_APP_SERVER_APPROVAL_REQUEST_METHODS.has(method);
4167
3935
  }
4168
- function formatExitValue(value) {
4169
- if (value === null || value === void 0) return "null";
4170
- if (typeof value === "string" || typeof value === "number") return String(value);
4171
- return "unknown";
4172
- }
4173
3936
  //#endregion
4174
- export { isMatchingDynamicToolTerminalDiagnostic as A, withDynamicToolTranscriptDetails as B, readCodexErrorNotification as C, handleDynamicToolCallWithTimeout as D, createCodexElicitationResponse as E, toCodexDynamicToolProgressResponse as F, toCodexDynamicToolProtocolResponse as I, resolveCodexToolAbortTerminalReason as L, resolveTerminalDynamicToolBatchAction as M, shouldBlockTerminalReleaseForNonTerminalDynamicToolResult as N, hasPendingDynamicToolTerminalDiagnostic as O, shouldReleaseTurnAfterTerminalDynamicTool as P, createFailedDynamicToolResponse as R, readCodexDynamicToolCallParams as S, readCodexTurnCompletedNotification as T, assertCodexThreadAcceptsDirectInput as _, isCodexAppServerBrokenPipeError as a, assertCodexThreadStartResponse as b, isCodexAppServerIndeterminateTransportError as c, isCodexAppServerRequestTimeoutError as d, isUnsupportedCodexAppServerVersionError as f, assertCodexPassiveTurnItems as g, assertCodexModelListResponse as h, isCodexAppServerApprovalRequest as i, resolveDynamicToolCallTimeoutMs as j, isDynamicToolTerminalDiagnosticEvent as k, isCodexAppServerOverloadError as l, CodexThreadDirectInputError as m, client_exports as n, isCodexAppServerConnectionClosedError as o, resolveCodexAppServerClientInstanceId as p, getCodexAppServerClientInstanceId as r, isCodexAppServerIndeterminateRequestCancellationError as s, CodexAppServerClient as t, isCodexAppServerPrewriteRequestCancellationError as u, assertCodexThreadForkResponse as v, readCodexTurn as w, assertCodexTurnStartResponse as x, assertCodexThreadResumeResponse as y, withDynamicToolExecutionState as z };
3937
+ export { handleDynamicToolCallWithTimeout as A, resolveCodexToolAbortTerminalReason as B, assertExactSupervisionModelSelection as C, readSupervisionResponseThreadId as D, readCodexTurnCompletedNotification as E, resolveTerminalDynamicToolBatchAction as F, failedToolResult as H, shouldBlockTerminalReleaseForNonTerminalDynamicToolResult as I, shouldReleaseTurnAfterTerminalDynamicTool as L, isDynamicToolTerminalDiagnosticEvent as M, isMatchingDynamicToolTerminalDiagnostic as N, resolveCodexThreadRolloutPath as O, resolveDynamicToolCallTimeoutMs as P, toCodexDynamicToolProgressResponse as R, assertCodexTurnStartResponse as S, readCodexErrorNotification as T, CODEX_APP_SERVER_OPT_OUT_NOTIFICATION_METHODS as U, createFailedDynamicToolResponse as V, assertCodexPassiveTurnItems as _, isCodexAppServerBrokenPipeError as a, assertCodexThreadResumeResponse as b, isCodexAppServerIndeterminateTransportError as c, isCodexAppServerRequestTimeoutError as d, isUnsupportedCodexAppServerVersionError as f, assertCodexModelListResponse as g, CodexThreadDirectInputError as h, isCodexAppServerApprovalRequest as i, hasPendingDynamicToolTerminalDiagnostic as j, createCodexElicitationResponse as k, isCodexAppServerOverloadError as l, CodexServerRequestResolvedError as m, client_exports as n, isCodexAppServerConnectionClosedError as o, resolveCodexAppServerClientInstanceId as p, getCodexAppServerClientInstanceId as r, isCodexAppServerIndeterminateRequestCancellationError as s, CodexAppServerClient as t, isCodexAppServerPrewriteRequestCancellationError as u, assertCodexThreadAcceptsDirectInput as v, readCodexDynamicToolCallParams as w, assertCodexThreadStartResponse as x, assertCodexThreadForkResponse as y, toCodexDynamicToolProtocolResponse as z };