@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
@@ -0,0 +1,561 @@
1
+ import { CODEX_INFERENCE_TRANSPORT_FAILURE, CodexInferenceAuthorizationError, authorizationFailure, createCodexInferenceDispatch, isTerminalResponse, n as createUploadAdmission, readProxyBody, readProxyWebSocketBody, t as MAX_BODY_BYTES } from "./inference-dispatch-CMZtjQyz.mjs";
2
+ import { t as createCodexInferenceContext } from "./inference-context-D-9gWlTR.mjs";
3
+ import { createPermitPool } from "openclaw/plugin-sdk/concurrency-runtime";
4
+ import { Writable } from "node:stream";
5
+ import { WebSocket, WebSocketServer, rejectWebSocketUpgrade } from "openclaw/plugin-sdk/websocket-runtime";
6
+ import { createServer } from "node:http";
7
+ import { createNodeProxyAgent } from "openclaw/plugin-sdk/fetch-runtime";
8
+ import { generateSecureToken } from "openclaw/plugin-sdk/secure-random-runtime";
9
+ import { fetchWithSsrFGuard, isBlockedHostnameOrIp, resolvePinnedHostnameWithPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
10
+ //#region extensions/codex/src/app-server/inference-proxy-http.ts
11
+ const OVERLOADED = "Codex inference relay is busy; retry on a fresh connection.";
12
+ const OVERLOAD_HEADERS = {
13
+ "content-type": "application/json",
14
+ "retry-after": "1"
15
+ };
16
+ const OVERLOAD_BODY = JSON.stringify({
17
+ type: "error",
18
+ status: 503,
19
+ error: {
20
+ type: "server_error",
21
+ code: "inference_relay_busy",
22
+ message: OVERLOADED
23
+ },
24
+ headers: { "retry-after": "1" }
25
+ });
26
+ const HOP_HEADERS = /* @__PURE__ */ new Set([
27
+ "connection",
28
+ "keep-alive",
29
+ "proxy-authenticate",
30
+ "proxy-authorization",
31
+ "te",
32
+ "trailer",
33
+ "transfer-encoding",
34
+ "upgrade",
35
+ "host",
36
+ "content-length"
37
+ ]);
38
+ function rejectBusyUpgrade(socket) {
39
+ rejectWebSocketUpgrade(socket, {
40
+ status: 503,
41
+ headers: { "Retry-After": "1" },
42
+ body: {
43
+ contentType: "application/json",
44
+ text: OVERLOAD_BODY
45
+ }
46
+ });
47
+ }
48
+ function relayHeaders(input) {
49
+ const excluded = new Set(HOP_HEADERS);
50
+ for (const token of (input.connection ?? "").split(",")) excluded.add(token.trim().toLowerCase());
51
+ const output = {};
52
+ for (const [key, value] of Object.entries(input)) if (value !== void 0 && !excluded.has(key.toLowerCase())) output[key.toLowerCase()] = Array.isArray(value) ? value.join(", ") : value;
53
+ return output;
54
+ }
55
+ //#endregion
56
+ //#region extensions/codex/src/app-server/inference-proxy.ts
57
+ const MAX_ERROR_BODY_BYTES = 1048576;
58
+ const MAX_WEBSOCKETS = 64;
59
+ const MAX_RESIDENTS = 80;
60
+ const REQUEST_TIMEOUT_MS = 3e4;
61
+ const HANDSHAKE_TIMEOUT_MS = 1e4;
62
+ const IDLE_WEBSOCKET_MS = 6e4;
63
+ /** Private, fixed-destination relay. No upstream credentials or model content are retained. */
64
+ async function createCodexInferenceProxy(params) {
65
+ const upstream = new URL(params.upstream);
66
+ if (upstream.protocol !== "https:" || upstream.username || upstream.password || upstream.hash) throw new Error("Codex inference requires a credential-free HTTPS upstream URL");
67
+ if (params.oauth && upstream.href.replace(/\/$/, "") !== "https://api.openai.com/v1") throw new Error("ChatGPT subscription sharing requires the public Responses endpoint");
68
+ const lifetime = new AbortController();
69
+ const assertCurrent = () => {
70
+ lifetime.signal.throwIfAborted();
71
+ params.assertCurrent();
72
+ };
73
+ const context = createCodexInferenceContext(assertCurrent);
74
+ const upstreamPath = upstream.pathname.replace(/\/+$/, "");
75
+ const pathPrefix = "/" + generateSecureToken({
76
+ bytes: 32,
77
+ redact: true
78
+ }) + (params.preserveAzureUrlFeatures ? "/azure-api." : "") + upstreamPath + (params.preserveCodexBackendRoutes && !upstreamPath.endsWith("/backend-api/codex") ? "/backend-api/codex" : params.preserveCodexBackendRoutes === false && upstreamPath.endsWith("/backend-api/codex") ? "/native-responses" : "");
79
+ const acquireUpload = createUploadAdmission();
80
+ const connections = /* @__PURE__ */ new Set();
81
+ const idleConnections = /* @__PURE__ */ new Set();
82
+ const residents = createPermitPool(MAX_RESIDENTS);
83
+ const tickets = /* @__PURE__ */ new Set();
84
+ const reclaimIdle = () => {
85
+ if (tickets.size < MAX_RESIDENTS || idleConnections.size === 0) return;
86
+ let acquired = 0;
87
+ let waiting = false;
88
+ let retiring = false;
89
+ for (const ticket of tickets) {
90
+ retiring ||= ticket.retiring;
91
+ if (ticket.release) acquired++;
92
+ else if (ticket.pending && !ticket.signal.aborted && Date.now() < ticket.deadlineAtMs) waiting = true;
93
+ }
94
+ if (!retiring && acquired === MAX_RESIDENTS && waiting) idleConnections.values().next().value?.();
95
+ };
96
+ const reserveResident = (socket, signal, deadlineAtMs) => {
97
+ if (tickets.size >= 96) return null;
98
+ const ticket = {
99
+ signal,
100
+ deadlineAtMs,
101
+ pending: true,
102
+ release: null,
103
+ retiring: false
104
+ };
105
+ tickets.add(ticket);
106
+ let finished = false;
107
+ const settle = () => {
108
+ if (!finished || !socket.closed || ticket.pending || !tickets.delete(ticket)) return;
109
+ socket.off("close", settle);
110
+ ticket.release?.();
111
+ ticket.release = null;
112
+ reclaimIdle();
113
+ };
114
+ socket.once("close", settle);
115
+ const ready = residents.acquire({
116
+ signal,
117
+ deadlineAtMs
118
+ }).then((release) => {
119
+ ticket.pending = false;
120
+ if (release && signal.aborted) release();
121
+ else ticket.release = release;
122
+ settle();
123
+ reclaimIdle();
124
+ return ticket.release !== null;
125
+ });
126
+ reclaimIdle();
127
+ return {
128
+ ready,
129
+ retireIdle() {
130
+ ticket.retiring = true;
131
+ },
132
+ finish() {
133
+ finished = true;
134
+ settle();
135
+ }
136
+ };
137
+ };
138
+ const wss = new WebSocketServer({
139
+ noServer: true,
140
+ maxPayload: MAX_BODY_BYTES,
141
+ perMessageDeflate: false
142
+ });
143
+ const handshakeHeaders = /* @__PURE__ */ new WeakMap();
144
+ wss.on("headers", (headers, request) => {
145
+ for (const [key, value] of Object.entries(handshakeHeaders.get(request) ?? {})) if (!key.startsWith("sec-websocket-")) headers.push(key + ": " + value);
146
+ handshakeHeaders.delete(request);
147
+ });
148
+ const resolveTarget = (request) => {
149
+ assertCurrent();
150
+ if (request.headers.origin || !request.url?.startsWith(pathPrefix + "/") || isBlockedHostnameOrIp(upstream.hostname)) throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
151
+ const suffix = request.url.slice(pathPrefix.length);
152
+ const rawPath = suffix.split("?", 1)[0] ?? suffix;
153
+ if (rawPath.startsWith("//") || rawPath.includes("\\") || /%2e|%2f|%5c|(?:^|\/)\.\.?(?:\/|$)/i.test(rawPath)) throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
154
+ const target = new URL(upstream);
155
+ const incoming = new URL(suffix, "http://localhost");
156
+ if (params.oauth && (incoming.pathname !== "/responses" || incoming.search)) throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
157
+ target.pathname = upstreamPath + incoming.pathname;
158
+ for (const [key, value] of incoming.searchParams) target.searchParams.append(key, value);
159
+ return {
160
+ target,
161
+ path: incoming.pathname,
162
+ sampling: incoming.pathname === "/responses"
163
+ };
164
+ };
165
+ const { prepare, prepareHttp } = createCodexInferenceDispatch({
166
+ context,
167
+ assertCurrent,
168
+ bindModelExecution: params.bindModelExecution,
169
+ requireAdmission: Boolean(params.oauth)
170
+ });
171
+ const server = createServer((req, res) => {
172
+ const socket = req.socket;
173
+ res.setHeader("Connection", "close");
174
+ const controller = new AbortController();
175
+ const signal = AbortSignal.any([lifetime.signal, controller.signal]);
176
+ const deadlineAtMs = Date.now() + REQUEST_TIMEOUT_MS;
177
+ let releasePermit = null;
178
+ let resident = null;
179
+ let upload;
180
+ let guarded;
181
+ const abort = () => controller.abort();
182
+ req.once("aborted", abort);
183
+ res.once("close", abort);
184
+ (async () => {
185
+ try {
186
+ const { target, sampling, path } = resolveTarget(req);
187
+ if (req.method !== "POST") throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
188
+ resident = reserveResident(socket, signal, deadlineAtMs);
189
+ const admitted = resident && await resident.ready;
190
+ signal.throwIfAborted();
191
+ assertCurrent();
192
+ if (!admitted) {
193
+ res.writeHead(503, OVERLOAD_HEADERS).end(OVERLOAD_BODY);
194
+ return;
195
+ }
196
+ releasePermit = await acquireUpload(signal, deadlineAtMs);
197
+ signal.throwIfAborted();
198
+ assertCurrent();
199
+ if (!releasePermit) {
200
+ res.writeHead(503, OVERLOAD_HEADERS).end(OVERLOAD_BODY);
201
+ return;
202
+ }
203
+ upload = await prepareHttp(req, sampling, path, signal, releasePermit, Boolean(params.oauth));
204
+ const preparedUpload = upload;
205
+ let body = upload.body;
206
+ for (let attempt = 0; attempt < (params.oauth ? 2 : 1); attempt++) {
207
+ const headers = {
208
+ ...relayHeaders(req.headers),
209
+ "content-length": String(upload.length)
210
+ };
211
+ const auth = await params.oauth?.resolve(attempt === 1);
212
+ const assertAuthorized = () => {
213
+ preparedUpload.assertCurrent();
214
+ auth?.assertCurrent();
215
+ };
216
+ assertAuthorized();
217
+ if (auth) {
218
+ for (const key of [
219
+ "authorization",
220
+ "chatgpt-account-id",
221
+ "openai-organization",
222
+ "openai-project"
223
+ ]) delete headers[key];
224
+ headers.authorization = `Bearer ${auth.token}`;
225
+ headers["x-openai-chatpass-test"] = "codex-direct";
226
+ }
227
+ const init = {
228
+ method: "POST",
229
+ headers,
230
+ body,
231
+ signal: upload.signal,
232
+ duplex: "half"
233
+ };
234
+ guarded = await fetchWithSsrFGuard({
235
+ url: target.toString(),
236
+ init,
237
+ signal: upload.signal,
238
+ beforeRequest: assertAuthorized,
239
+ requireHttps: true,
240
+ maxRedirects: 0,
241
+ capture: false,
242
+ mode: "trusted_env_proxy",
243
+ auditContext: "codex-parent-local-inference"
244
+ });
245
+ assertAuthorized();
246
+ if (!upload.retry || guarded.response.status !== 401 || attempt === 1) {
247
+ upload.commit?.();
248
+ break;
249
+ }
250
+ await guarded.response.body?.cancel();
251
+ await guarded.release();
252
+ guarded = void 0;
253
+ body = upload.retry();
254
+ }
255
+ if (!guarded) throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
256
+ upload.assertCurrent();
257
+ const headers = Object.fromEntries(guarded.response.headers);
258
+ delete headers["content-encoding"];
259
+ res.writeHead(guarded.response.status, relayHeaders(headers));
260
+ if (!guarded.response.body) res.end();
261
+ else await guarded.response.body.pipeTo(Writable.toWeb(res), { signal: upload.signal });
262
+ } catch (error) {
263
+ if (!res.headersSent && !res.destroyed) {
264
+ const denied = authorizationFailure(error);
265
+ if (denied) res.writeHead(403, { "content-type": "application/json" }).end(denied);
266
+ else res.writeHead(502, { "content-type": "text/plain" }).end(CODEX_INFERENCE_TRANSPORT_FAILURE);
267
+ } else res.destroy();
268
+ } finally {
269
+ upload?.settle();
270
+ releasePermit?.();
271
+ req.off("aborted", abort);
272
+ res.off("close", abort);
273
+ await guarded?.release().catch(() => void 0);
274
+ upload?.releaseModelExecution();
275
+ resident?.finish();
276
+ }
277
+ })();
278
+ });
279
+ server.maxConnections = 128;
280
+ server.requestTimeout = REQUEST_TIMEOUT_MS;
281
+ server.headersTimeout = HANDSHAKE_TIMEOUT_MS;
282
+ server.on("upgrade", (req, socket, head) => {
283
+ (async () => {
284
+ let remote;
285
+ let local;
286
+ let proxyAgent;
287
+ let upstreamClosed = Promise.resolve();
288
+ let finishSetup = () => {};
289
+ const setupSettled = new Promise((resolve) => {
290
+ finishSetup = resolve;
291
+ });
292
+ let resident = null;
293
+ const controller = new AbortController();
294
+ const deadlineAtMs = Date.now() + HANDSHAKE_TIMEOUT_MS;
295
+ let releasePermit = null;
296
+ let framePending = false;
297
+ let idleTimer;
298
+ let handshakeTimer;
299
+ let closing = false;
300
+ const finish = (status) => {
301
+ if (closing) return;
302
+ closing = true;
303
+ if (idleConnections.has(close)) resident?.retireIdle();
304
+ clearTimeout(idleTimer);
305
+ clearTimeout(handshakeTimer);
306
+ socket.off("end", close);
307
+ connections.delete(close);
308
+ idleConnections.delete(close);
309
+ controller.abort();
310
+ remote?.terminate();
311
+ local?.terminate();
312
+ proxyAgent?.destroy();
313
+ if (status && !local && !socket.destroyed && !socket.writableEnded) rejectWebSocketUpgrade(socket, {
314
+ status,
315
+ body: {
316
+ contentType: "text/plain",
317
+ text: CODEX_INFERENCE_TRANSPORT_FAILURE
318
+ }
319
+ });
320
+ else socket.destroy();
321
+ setupSettled.then(() => upstreamClosed).then(() => {
322
+ releasePermit?.();
323
+ releasePermit = null;
324
+ resident?.finish();
325
+ });
326
+ };
327
+ const close = () => finish();
328
+ const failHandshake = () => finish(Date.now() >= deadlineAtMs ? 504 : 502);
329
+ try {
330
+ const { target, sampling, path } = resolveTarget(req);
331
+ if (params.oauth) throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
332
+ if (!sampling && path !== "/guardian" && path !== "/guardian-classifier") throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
333
+ if (connections.size >= MAX_WEBSOCKETS) idleConnections.values().next().value?.();
334
+ if (connections.size >= MAX_WEBSOCKETS) {
335
+ rejectBusyUpgrade(socket);
336
+ return;
337
+ }
338
+ connections.add(close);
339
+ socket.once("close", close);
340
+ socket.once("error", close);
341
+ socket.once("end", close);
342
+ const signal = AbortSignal.any([lifetime.signal, controller.signal]);
343
+ resident = reserveResident(socket, signal, deadlineAtMs);
344
+ const admitted = resident && await resident.ready;
345
+ signal.throwIfAborted();
346
+ assertCurrent();
347
+ if (!admitted) {
348
+ rejectBusyUpgrade(socket);
349
+ return;
350
+ }
351
+ releasePermit = await acquireUpload(signal, deadlineAtMs);
352
+ signal.throwIfAborted();
353
+ assertCurrent();
354
+ if (!releasePermit) {
355
+ rejectBusyUpgrade(socket);
356
+ return;
357
+ }
358
+ handshakeTimer = setTimeout(() => finish(504), Math.max(1, deadlineAtMs - Date.now()));
359
+ handshakeTimer.unref();
360
+ const assertHandshakeCurrent = () => {
361
+ assertCurrent();
362
+ signal.throwIfAborted();
363
+ if (Date.now() >= deadlineAtMs) throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
364
+ };
365
+ proxyAgent = createNodeProxyAgent({
366
+ mode: "env",
367
+ targetUrl: target.href
368
+ });
369
+ const lookup = proxyAgent ? void 0 : (await resolvePinnedHostnameWithPolicy(target.hostname, { signal })).lookup;
370
+ assertHandshakeCurrent();
371
+ target.protocol = "wss:";
372
+ const headers = relayHeaders(req.headers);
373
+ for (const key of Object.keys(headers)) if (key.startsWith("sec-websocket-")) delete headers[key];
374
+ remote = new WebSocket(target, {
375
+ headers,
376
+ ...proxyAgent ? { agent: proxyAgent } : { lookup },
377
+ followRedirects: false,
378
+ perMessageDeflate: false,
379
+ maxPayload: MAX_BODY_BYTES,
380
+ handshakeTimeout: Math.max(1, deadlineAtMs - Date.now()),
381
+ finishRequest(request) {
382
+ let socketClosed = Promise.resolve();
383
+ request.once("socket", (upstreamSocket) => {
384
+ socketClosed = new Promise((resolve) => {
385
+ upstreamSocket.once("close", () => resolve());
386
+ });
387
+ });
388
+ upstreamClosed = new Promise((resolve) => {
389
+ request.once("close", () => {
390
+ socketClosed.then(resolve);
391
+ });
392
+ });
393
+ request.end();
394
+ }
395
+ });
396
+ remote.once("upgrade", (response) => {
397
+ handshakeHeaders.set(req, relayHeaders(response.headers));
398
+ });
399
+ remote.once("error", failHandshake);
400
+ remote.once("close", failHandshake);
401
+ remote.once("unexpected-response", (_request, response) => {
402
+ (async () => {
403
+ try {
404
+ const body = await readProxyBody(response, MAX_ERROR_BODY_BYTES);
405
+ assertHandshakeCurrent();
406
+ clearTimeout(handshakeTimer);
407
+ const failureHeaders = Object.entries(relayHeaders(response.headers)).map(([key, value]) => key + ": " + value);
408
+ failureHeaders.push("Connection: close", "Content-Length: " + body.length);
409
+ const status = "HTTP/1.1 " + response.statusCode + " " + (response.statusMessage ?? "Upstream refused");
410
+ socket.end(Buffer.concat([Buffer.from(status + "\r\n" + failureHeaders.join("\r\n") + "\r\n\r\n"), body]), close);
411
+ } catch {
412
+ failHandshake();
413
+ }
414
+ })();
415
+ });
416
+ remote.once("open", () => {
417
+ try {
418
+ assertHandshakeCurrent();
419
+ wss.handleUpgrade(req, socket, head, (accepted) => {
420
+ clearTimeout(handshakeTimer);
421
+ socket.off("end", close);
422
+ local = accepted;
423
+ accepted.once("error", close);
424
+ accepted.once("close", close);
425
+ let releaseFrame = () => {};
426
+ let settleFrame = () => {};
427
+ const idle = (reclaimable = true) => {
428
+ framePending = false;
429
+ idleConnections.delete(close);
430
+ if (reclaimable) idleConnections.add(close);
431
+ clearTimeout(idleTimer);
432
+ idleTimer = setTimeout(close, IDLE_WEBSOCKET_MS);
433
+ idleTimer.unref();
434
+ reclaimIdle();
435
+ };
436
+ releasePermit?.();
437
+ releasePermit = null;
438
+ idle(false);
439
+ const forward = async (prepared) => {
440
+ let releaseUpload = null;
441
+ try {
442
+ const requestSignal = AbortSignal.any([signal, ...prepared.signal ? [prepared.signal] : []]);
443
+ releaseUpload = await acquireUpload(requestSignal, Date.now() + REQUEST_TIMEOUT_MS, prepared.bytes.length);
444
+ requestSignal.throwIfAborted();
445
+ prepared.assertCurrent();
446
+ if (!releaseUpload) {
447
+ accepted.send(OVERLOAD_BODY, { binary: false }, close);
448
+ return;
449
+ }
450
+ if (!remote || remote.readyState !== WebSocket.OPEN || remote.bufferedAmount + prepared.bytes.length > 33554432) throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
451
+ const release = releaseUpload;
452
+ remote.send(prepared.bytes, { binary: false }, (error) => {
453
+ release();
454
+ if (error) close();
455
+ });
456
+ } catch {
457
+ releaseUpload?.();
458
+ close();
459
+ }
460
+ };
461
+ accepted.on("message", (data, binary) => {
462
+ if (framePending) {
463
+ close();
464
+ return;
465
+ }
466
+ framePending = true;
467
+ clearTimeout(idleTimer);
468
+ idleConnections.delete(close);
469
+ releaseFrame();
470
+ (async () => {
471
+ let prepared;
472
+ try {
473
+ if (binary) throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
474
+ prepared = await prepare(readProxyWebSocketBody(data), sampling, path, req.headers, signal, "websocket");
475
+ prepared.assertCurrent();
476
+ const frame = prepared;
477
+ const onAbort = () => close();
478
+ frame.signal.addEventListener("abort", onAbort, { once: true });
479
+ frame.contextSignal?.addEventListener("abort", onAbort, { once: true });
480
+ const releaseModel = () => {
481
+ frame.signal.removeEventListener("abort", onAbort);
482
+ frame.release();
483
+ };
484
+ settleFrame = releaseModel;
485
+ releaseFrame = () => {
486
+ frame.contextSignal?.removeEventListener("abort", onAbort);
487
+ releaseModel();
488
+ };
489
+ frame.signal.throwIfAborted();
490
+ await forward(frame);
491
+ } catch (error) {
492
+ prepared?.release();
493
+ const denied = authorizationFailure(error);
494
+ if (denied && accepted.readyState === WebSocket.OPEN) accepted.send(denied, { binary: false }, close);
495
+ else close();
496
+ }
497
+ })();
498
+ });
499
+ accepted.once("close", () => releaseFrame());
500
+ remote.on("message", (data, binary) => {
501
+ if (accepted.readyState !== WebSocket.OPEN || accepted.bufferedAmount + readProxyWebSocketBody(data).length > 33554432) {
502
+ close();
503
+ return;
504
+ }
505
+ const terminal = !binary && isTerminalResponse(readProxyWebSocketBody(data));
506
+ const releaseCompletedFrame = terminal ? settleFrame : void 0;
507
+ accepted.send(data, { binary }, (error) => {
508
+ if (error) close();
509
+ else if (terminal && connections.has(close)) {
510
+ releaseCompletedFrame?.();
511
+ idle();
512
+ }
513
+ });
514
+ });
515
+ });
516
+ } catch {
517
+ failHandshake();
518
+ }
519
+ });
520
+ } catch {
521
+ if (connections.has(close)) failHandshake();
522
+ else close();
523
+ } finally {
524
+ finishSetup();
525
+ }
526
+ })();
527
+ });
528
+ const close = () => {
529
+ lifetime.abort();
530
+ context.close();
531
+ for (const closeConnection of connections) closeConnection();
532
+ server.close();
533
+ server.closeAllConnections();
534
+ wss.close();
535
+ };
536
+ try {
537
+ await new Promise((resolve, reject) => {
538
+ server.once("error", reject);
539
+ server.listen(0, "127.0.0.1", () => {
540
+ server.off("error", reject);
541
+ resolve();
542
+ });
543
+ });
544
+ assertCurrent();
545
+ server.on("error", close);
546
+ const address = server.address();
547
+ if (!address || typeof address === "string") throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
548
+ return {
549
+ context,
550
+ upstream: upstream.toString(),
551
+ baseUrl: "http://127.0.0.1:" + address.port + pathPrefix,
552
+ assertCurrent,
553
+ close
554
+ };
555
+ } catch (error) {
556
+ close();
557
+ throw error;
558
+ }
559
+ }
560
+ //#endregion
561
+ export { CodexInferenceAuthorizationError, createCodexInferenceProxy };
@@ -1,10 +1,11 @@
1
- import { d as readCodexPluginConfig } from "./config-parsing-CcB9iPoq.mjs";
2
- import { g as assertCodexPassiveTurnItems } from "./client-vXs2929Q.mjs";
3
- import { i as resolveCodexAppServerHomeScope } from "./config-options-BsanJ8QG.mjs";
4
- import "./config-CedDWjM-.mjs";
5
- import { Z as resolveCodexAppServerPreparedAuthHandoff } from "./shared-client-BpTtuLQ5.mjs";
6
- import { runBoundedCodexAppServerTurn } from "./bounded-turn-BtlZcivC.mjs";
7
- import { a as createAttributedCodexAssistantMessage } from "./event-projector-assistant-message-DNUR1s0A.mjs";
1
+ import { d as readCodexPluginConfig } from "./config-parsing-b088LyhT.mjs";
2
+ import { i as resolveCodexAppServerHomeScope } from "./config-options-CzyWLTJt.mjs";
3
+ import "./config-DKhXquav.mjs";
4
+ import { tt as resolveCodexAppServerPreparedAuthHandoff } from "./shared-client-DqyTMYug.mjs";
5
+ import { _ as assertCodexPassiveTurnItems } from "./client-N0JpgSzF.mjs";
6
+ import { runBoundedCodexAppServerTurn } from "./bounded-turn-CbjoN2OW.mjs";
7
+ import { t as resolveCodexBoundedTurnIsolation } from "./bounded-turn-isolation-B8K_ylqk.mjs";
8
+ import { a as createAttributedCodexAssistantMessage } from "./event-projector-assistant-message-CigreO4K.mjs";
8
9
  //#region extensions/codex/src/app-server/isolated-completion.ts
9
10
  /** Runs prompt-only Codex inference on an ephemeral, ring-zero native thread. */
10
11
  async function runCodexIsolatedCompletion(params, options) {
@@ -12,13 +13,14 @@ async function runCodexIsolatedCompletion(params, options) {
12
13
  const authorization = params.authorization;
13
14
  if (authorization.owner !== "harness") throw new Error("Codex native isolated completion requires harness-owned authorization.");
14
15
  const pluginConfig = readCodexPluginConfig(options.pluginConfig);
16
+ const homeScope = resolveCodexAppServerHomeScope({ appServer: pluginConfig.appServer });
15
17
  const authRequirement = authorization.plan.modelRoute?.authRequirement;
16
18
  const authHandoff = await resolveCodexAppServerPreparedAuthHandoff({
17
19
  authRequirement,
18
20
  authProfileId: authorization.plan.forwardedAuthProfileId,
19
21
  authProfileStore: authorization.authProfileStore,
20
22
  agentDir: params.agentDir,
21
- homeScope: resolveCodexAppServerHomeScope({ appServer: pluginConfig.appServer }),
23
+ homeScope,
22
24
  config: params.config,
23
25
  subscriptionProfileRequiredError: "Prepared Codex subscription route requires a scoped native OAuth or token profile.",
24
26
  subscriptionProfileUnusableError: `Prepared Codex auth profile "${authorization.plan.forwardedAuthProfileId}" is unusable.`
@@ -34,6 +36,7 @@ async function runCodexIsolatedCompletion(params, options) {
34
36
  ...authSelection,
35
37
  authRequirement,
36
38
  timeoutMs: params.timeoutMs,
39
+ thinkLevel: params.thinkLevel,
37
40
  signal: params.abortSignal,
38
41
  assertCurrent: params.assertCurrent,
39
42
  agentDir: params.agentDir,
@@ -47,11 +50,12 @@ async function runCodexIsolatedCompletion(params, options) {
47
50
  text_elements: []
48
51
  }],
49
52
  requiredModalities: ["text"],
50
- isolation: "configured-transport",
51
- requireNoExternalCapabilities: true
53
+ isolation: resolveCodexBoundedTurnIsolation(options),
54
+ requireNoExternalCapabilities: true,
55
+ allowEmptyText: params.outputTextPolicy === "strict-visible"
52
56
  });
53
57
  params.assertCurrent?.();
54
- assertCodexPassiveTurnItems(result.items, params.prompt, "isolated completion");
58
+ assertCodexPassiveTurnItems(result.items, params.prompt, "isolated completion", { allowManagedHookPrompts: result.managedHooksEnabled });
55
59
  return { assistant: createAttributedCodexAssistantMessage({
56
60
  api: "openai-chatgpt-responses",
57
61
  provider: params.provider,