@openclaw/codex 2026.9.6 → 2026.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/assets/icon.png +0 -0
- package/dist/.setup/{account-usage-runtime-Eem_WGqY.mjs → account-usage-runtime-DFhbh1zz.mjs} +5 -5
- package/dist/.setup/{apply-DDOi8uNx.mjs → apply-D3GcSoSa.mjs} +22 -36
- package/dist/.setup/{attempt-client-cleanup-CEv1cKwF.mjs → attempt-client-cleanup-DOP-cW5j.mjs} +128 -37
- package/dist/.setup/attempt-workspace-context-C5HigshI.mjs +164 -0
- package/dist/.setup/{auth-binding-DhLWa_7K.mjs → auth-binding-BLWz7stm.mjs} +14 -1
- package/dist/.setup/{auth-cache-key-B2mpaI9D.mjs → auth-cache-key-Dbvq-QgB.mjs} +36 -34
- package/dist/.setup/{auth-profile-WqZtZfXN.mjs → auth-profile-B0okYl2D.mjs} +1 -2
- package/dist/.setup/auth-start-options-BPIPeEX8.mjs +44 -0
- package/dist/.setup/{binding-connection-ThoatDcb.mjs → binding-connection-DTtN1KrX.mjs} +2 -2
- package/dist/.setup/{binding-connection.runtime-yoHrABt-.mjs → binding-connection.runtime-6TpgD1M6.mjs} +4 -4
- package/dist/.setup/{bounded-turn-B2HScEgT.mjs → bounded-turn-CbjoN2OW.mjs} +15 -18
- package/dist/.setup/bounded-turn-isolation-B8K_ylqk.mjs +14 -0
- package/dist/.setup/{build-state-C7EnDVgr.mjs → build-state-Da1_z0kd.mjs} +1 -1
- package/dist/.setup/{capabilities-CDXOOFdZ.mjs → capabilities-B3WEZl4e.mjs} +2 -10
- package/dist/.setup/{client-Cs08OXVQ.mjs → client-N0JpgSzF.mjs} +138 -399
- package/dist/.setup/{client-catalog-response-BMgt_4q4.mjs → client-catalog-response-5HHLdcde.mjs} +1 -1
- package/dist/.setup/{command-dispatch-B4JuOsOk.mjs → command-dispatch-BeAoaovI.mjs} +5 -8
- package/dist/.setup/{command-formatters-Bmqvr9tO.mjs → command-formatters-R3ckE3Co.mjs} +29 -61
- package/dist/.setup/{command-handlers-DW7Lx9oH.mjs → command-handlers-ylTMS00z.mjs} +222 -343
- package/dist/.setup/{command-rpc-DixIj3HW.mjs → command-rpc-CGJGUQ6Y.mjs} +15 -18
- package/dist/.setup/compact-C2WamavS.mjs +776 -0
- package/dist/.setup/{config-BoTP_mrL.mjs → config-DKhXquav.mjs} +26 -28
- package/dist/.setup/{config-options-BvaRs51b.mjs → config-options-CzyWLTJt.mjs} +24 -37
- package/dist/.setup/{config-parsing-CcB9iPoq.mjs → config-parsing-b088LyhT.mjs} +57 -60
- package/dist/.setup/{config-runtime-C8Rw1m1m.mjs → config-runtime-C0NbLms1.mjs} +2 -2
- package/dist/.setup/{config-security-BEReZ6go.mjs → config-security-CE-FcGw9.mjs} +32 -111
- package/dist/.setup/{config-utils-DujwEnhg.mjs → config-utils-D0CXecki.mjs} +3 -13
- package/dist/.setup/context-engine-projection-PezSESth.mjs +387 -0
- package/dist/.setup/{conversation-binding-DP-gMrBP.mjs → conversation-binding-3Min8qvP.mjs} +67 -90
- package/dist/.setup/{conversation-binding-data-CrcyZk6O.mjs → conversation-binding-data-C746z5Pn.mjs} +8 -12
- package/dist/.setup/{conversation-control-uK9Jomlc.mjs → conversation-control-CEP8X5JC.mjs} +8 -8
- package/dist/.setup/{cyber-failover-DYwbmf1o.mjs → cyber-failover-XV0nNRZu.mjs} +1 -1
- package/dist/.setup/{cyber-failover-notice-e9G3J9-e.mjs → cyber-failover-notice-RNpGpTyP.mjs} +1 -1
- package/dist/.setup/{dynamic-tools-BDXl-8Cw.mjs → dynamic-tools-DzlsLUuS.mjs} +2305 -2606
- package/dist/.setup/{effective-mcp-catalog-CvnvnGIe.mjs → effective-mcp-catalog-CxUtC-xG.mjs} +8 -17
- package/dist/.setup/{ephemeral-turn-poidXgek.mjs → ephemeral-turn-CDsPJOa2.mjs} +3 -3
- package/dist/.setup/event-projector-assistant-message-CigreO4K.mjs +69 -0
- package/dist/.setup/{event-projector-usage-CnBS8Wa3.mjs → event-projector-usage-03R0I2dM.mjs} +3 -25
- package/dist/.setup/event-projector-values-DJSz8BTk.mjs +106 -0
- package/dist/.setup/incognito-session-DWYapfwf.mjs +2 -0
- package/dist/.setup/{inference-context-D96l9-ew.mjs → inference-context-D-9gWlTR.mjs} +16 -18
- package/dist/.setup/inference-dispatch-CMZtjQyz.mjs +359 -0
- package/dist/.setup/inference-metadata-CgIf7sOx.mjs +81 -0
- package/dist/.setup/{inference-proxy-b-aJMSxm.mjs → inference-proxy-DhcXOgUE.mjs} +174 -214
- package/dist/.setup/{isolated-completion-BIZFhTNG.mjs → isolated-completion-Dm3PzxJk.mjs} +9 -12
- package/dist/.setup/{managed-binary-BnshlFag.mjs → managed-binary-kiWRhNRE.mjs} +8 -12
- package/dist/.setup/{model-catalog-CfXJf9Ay.mjs → model-catalog-PAuZgJC6.mjs} +11 -10
- package/dist/.setup/model-runtime-BdqzOMkU.mjs +11 -0
- package/dist/.setup/{models-KnqBv0hE.mjs → models-DHXZtVVk.mjs} +9 -18
- package/dist/.setup/{native-auth-rWbGbMn3.mjs → native-auth-CuG53tu4.mjs} +4 -4
- package/dist/.setup/{native-execution-policy-umd0tgh4.mjs → native-execution-policy-BxZJy5mP.mjs} +5 -30
- package/dist/.setup/{native-subagent-monitor-D3filLY2.mjs → native-subagent-monitor-Dpsmf2wz.mjs} +4395 -3609
- package/dist/.setup/native-subagent-pending-assignments-DwkCzLvD.mjs +203 -0
- package/dist/.setup/native-task-assignments-DMQ0g3hu.mjs +194 -0
- package/dist/.setup/{node-cli-sessions-r3avj02l.mjs → node-cli-sessions-HC4W6FLI.mjs} +19 -49
- package/dist/.setup/{node-exec-server.runtime-BDwWXVpK.mjs → node-exec-server.runtime-BgBfWQqo.mjs} +3 -6
- package/dist/.setup/{plan-CN3VwfNU.mjs → plan-Y-QIvrKB.mjs} +49 -92
- package/dist/.setup/{plugin-activation-DT3MNtqj.mjs → plugin-activation-cNHRfaxU.mjs} +8 -36
- package/dist/.setup/{plugin-app-cache-key-B2CsSdnV.mjs → plugin-app-cache-key-BL9B5H0L.mjs} +6 -23
- package/dist/.setup/{plugin-inventory-BoRei8Z4.mjs → plugin-inventory-Cky2XJUw.mjs} +21 -21
- package/dist/.setup/{plugin-marketplace-discovery-CDOi8IFs.mjs → plugin-marketplace-discovery-D_dV9FXa.mjs} +18 -24
- package/dist/.setup/{plugin-metadata-cache-Ctmo83k_.mjs → plugin-metadata-cache-DsjsL1dr.mjs} +115 -175
- package/dist/.setup/{provider-BOsxQHOM.mjs → provider-DH8NSzGt.mjs} +11 -14
- package/dist/.setup/{provider-capabilities-BfE88FZ5.mjs → provider-capabilities-CAxoF-X1.mjs} +13 -18
- package/dist/.setup/{rate-limits-CMU3DUD0.mjs → rate-limits-B7-X2TgG.mjs} +9 -31
- package/dist/.setup/{request-D2L0zMrq.mjs → request-BHZ1nz8d.mjs} +7 -6
- package/dist/.setup/responses-oauth-twnuTaAa.mjs +93 -0
- package/dist/.setup/rpc-error-BlD2vuzn.mjs +31 -0
- package/dist/.setup/{run-attempt-BHu11r7h.mjs → run-attempt-D8RZUOzY.mjs} +1035 -1023
- package/dist/.setup/{run-attempt-lifecycle-B7JbY4-F.mjs → run-attempt-lifecycle-C-6O3Exn.mjs} +10 -24
- package/dist/.setup/{runtime-artifact-CLZ8udh-.mjs → runtime-artifact-DDQ-HGXf.mjs} +16 -4
- package/dist/.setup/runtime-artifact-connection-D68qQn1m.mjs +78 -0
- package/dist/.setup/sandbox-guard-DjCz2eOw.mjs +126 -0
- package/dist/.setup/scope-DOC1Xjc8.mjs +6 -0
- package/dist/.setup/session-binding-DGCYAfvD.mjs +443 -0
- package/dist/.setup/{session-binding-record-BGoz8wOK.mjs → session-binding-record-Oe9L-CNY.mjs} +52 -130
- package/dist/.setup/{session-binding-sidecars-BlB5EvIS.mjs → session-binding-sidecars-jo6H8dFr.mjs} +196 -17
- package/dist/.setup/{session-catalog-Pno1xGcl.mjs → session-catalog-4sCdv5qx.mjs} +170 -324
- package/dist/.setup/{session-catalog-adoption-BI6UTDZT.mjs → session-catalog-adoption-BU_pHWG7.mjs} +7 -6
- package/dist/.setup/{session-catalog-archive-lHBqzhaO.mjs → session-catalog-archive-spHfihri.mjs} +6 -6
- package/dist/.setup/session-catalog-events-DePDzzjc.mjs +139 -0
- package/dist/.setup/session-catalog-home-id-vlih0B_g.mjs +22 -0
- package/dist/.setup/{session-catalog-index-B9_VQIUz.mjs → session-catalog-index-CZvDzC6z.mjs} +126 -122
- package/dist/.setup/{session-catalog-index-order-hcdz07yN.mjs → session-catalog-index-order-BcQpHks3.mjs} +1 -1
- package/dist/.setup/{session-catalog-index-state-Dgh8ORJm.mjs → session-catalog-index-state-TeO7EyO-.mjs} +3 -2
- package/dist/.setup/session-catalog-limits-DDxOsQeC.mjs +14 -0
- package/dist/.setup/session-catalog-list-request-CvtxrYSe.mjs +170 -0
- package/dist/.setup/session-catalog-native-projection-DjhwGL6x.mjs +178 -0
- package/dist/.setup/{session-catalog-node-adoption-ITddWx_X.mjs → session-catalog-node-adoption-DgXvSGu0.mjs} +10 -27
- package/dist/.setup/{session-catalog-node-continue-6g6qi4A9.mjs → session-catalog-node-continue-DjKXHBbi.mjs} +8 -10
- package/dist/.setup/session-catalog-node-lookup-CtAXI5W5.mjs +56 -0
- package/dist/.setup/{session-catalog-native-projection-DowriLid.mjs → session-catalog-parsing-CPGaPYr-.mjs} +11 -194
- package/dist/.setup/{session-catalog-projection-zK_PUsiE.mjs → session-catalog-projection-Cr5qP5Dj.mjs} +6 -4
- package/dist/.setup/session-catalog-provenance-DoAvktcj.mjs +95 -0
- package/dist/.setup/{session-cli-irrD-uo7.mjs → session-cli-Cn_nCqfq.mjs} +9 -22
- package/dist/.setup/{session-history-BrqhSCf9.mjs → session-history-D83lJWHG.mjs} +4 -6
- package/dist/.setup/{session-history-import-D-3wAgOP.mjs → session-history-import-WhX-X33a.mjs} +7 -10
- package/dist/.setup/session-history-read-Ov3StuL4.mjs +133 -0
- package/dist/.setup/{session-history.worker-CaCh0xF_.mjs → session-history.worker-MnPKncqP.mjs} +9 -5
- package/dist/.setup/session-initialization-6aveB9qb.mjs +22 -0
- package/dist/.setup/{session-permission-policy-BI1QK_98.mjs → session-permission-policy-Ci_fVX6y.mjs} +4 -8
- package/dist/.setup/{session-retirement-BH-S6qkJ.mjs → session-retirement-qMTxkNx2.mjs} +17 -17
- package/dist/.setup/{settled-turn-context-fmwouT5I.mjs → settled-turn-context-D4yj4rxf.mjs} +1 -1
- package/dist/.setup/{settled-turn-finalizer-DiAi6Kx6.mjs → settled-turn-finalizer-BsvEabkw.mjs} +14 -10
- package/dist/.setup/{shared-client-DA4VR4Eb.mjs → shared-client-DqyTMYug.mjs} +783 -412
- package/dist/.setup/shared-client-lifecycle-DJIgqgMw.mjs +153 -0
- package/dist/.setup/{side-question-BJ1wSDcB.mjs → side-question-C4kCmQy1.mjs} +79 -143
- package/dist/.setup/{source-CUzJq5WN.mjs → source-CS_7GFJZ.mjs} +80 -137
- package/dist/.setup/{thread-lifecycle-B3mfz1TG.mjs → thread-lifecycle-DPflntEJ.mjs} +294 -737
- package/dist/.setup/{incognito-session-uhrBF6wJ.mjs → thread-ownership-queue-Dp24d7-F.mjs} +1 -2
- package/dist/.setup/{thread-ownership-DcTtAcXj.mjs → thread-ownership-roNP0l1c.mjs} +45 -10
- package/dist/.setup/{thread-policy-DGuQsuFC.mjs → thread-policy-DTd-DtkX.mjs} +46 -7
- package/dist/.setup/{thread-requests-BLvGkP2R.mjs → thread-requests-B_bRnMGN.mjs} +199 -302
- package/dist/.setup/{thread-resume-DIBXwOpE.mjs → thread-resume-CdDaoc7T.mjs} +6 -6
- package/dist/.setup/{timeout-C910MdAB.mjs → timeout-CXOfNoaX.mjs} +1 -35
- package/dist/.setup/{transcript-history-projection-ZZpkFkJ_.mjs → transcript-history-projection-DRSifI-1.mjs} +17 -89
- package/dist/.setup/{transcript-mirror-attestation-CzM-94NC.mjs → transcript-mirror-attestation-YSegaktH.mjs} +3 -4
- package/dist/.setup/{transcript-mirror-BtHDBp1G.mjs → transcript-mirror-kxmCYsuF.mjs} +7 -9
- package/dist/.setup/{transport-stdio-h2VHOskC.mjs → transport-stdio-Bdegpn2V.mjs} +5 -22
- package/dist/.setup/transport-websocket-BTBE-LD9.mjs +211 -0
- package/dist/.setup/{upstream-prompt-provenance-LphB8slG.mjs → upstream-prompt-provenance-fXkKbPVC.mjs} +3 -9
- package/dist/.setup/{upstream-session-fork-BUr4OUbC.mjs → upstream-session-fork-CBeVjBpT.mjs} +23 -23
- package/dist/.setup/{usage-BML0r-ua.mjs → usage-BMzNxeR_.mjs} +4 -4
- package/dist/.setup/{usage-limit-error-DUMbefVY.mjs → usage-limit-error-QXerDo3i.mjs} +4 -19
- package/dist/.setup/{web-search-provider.runtime-CDKlN-Rv.mjs → web-search-provider.runtime-P77OUeoo.mjs} +8 -19
- package/dist/api.js +9 -11
- package/dist/catalog-page.worker.js +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/doctor-contract-api.js +50 -8
- package/dist/harness.js +344 -1
- package/dist/index.js +193 -245
- package/dist/media-understanding-provider.js +9 -22
- package/dist/migration-provider-api.js +1 -1
- package/dist/provider-discovery.js +1 -1
- package/dist/session-history-worker-runtime.js +3 -3
- package/dist/session-history.worker.js +1 -1
- package/openclaw.plugin.json +14 -2
- package/package.json +7 -6
- package/dist/.setup/attempt-workspace-context-DUVEn_CS.mjs +0 -331
- package/dist/.setup/compact-Du5UvtxA.mjs +0 -680
- package/dist/.setup/event-projector-assistant-message-BsruvNrH.mjs +0 -103
- package/dist/.setup/event-projector-items-C6L_5ZiT.mjs +0 -234
- package/dist/.setup/harness-a_MsE4-_.mjs +0 -355
- package/dist/.setup/history-rejection-B4nOXNXF.mjs +0 -13
- package/dist/.setup/image-payload-sanitizer-tupAr-2o.mjs +0 -79
- package/dist/.setup/local-runtime-attribution-B_2mnqhb.mjs +0 -19
- package/dist/.setup/native-subagent-history-0nYYgo0k.mjs +0 -148
- package/dist/.setup/native-subagent-task-ids-wb8CKZGN.mjs +0 -441
- package/dist/.setup/plugin-approval-roundtrip-C0MZzCuP.mjs +0 -122
- package/dist/.setup/rolldown-runtime-8H4AJuhK.mjs +0 -14
- package/dist/.setup/sandbox-guard-C2sRMOEY.mjs +0 -166
- package/dist/.setup/session-binding-Cm0apEbd.mjs +0 -692
- package/dist/.setup/session-catalog-events-Bj6j94E_.mjs +0 -347
- package/dist/.setup/session-history-read-B3ZfSUbF.mjs +0 -50
- package/dist/.setup/session-initialization-rcgbZiid.mjs +0 -75
- package/dist/.setup/thread-history-page-DoVpnHim.mjs +0 -83
|
@@ -1,83 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { Writable, getDefaultHighWaterMark } from "node:stream";
|
|
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";
|
|
6
5
|
import { WebSocket, WebSocketServer, rejectWebSocketUpgrade } from "openclaw/plugin-sdk/websocket-runtime";
|
|
7
6
|
import { createServer } from "node:http";
|
|
8
|
-
import { createPermitPool } from "openclaw/plugin-sdk/concurrency-runtime";
|
|
9
7
|
import { createNodeProxyAgent } from "openclaw/plugin-sdk/fetch-runtime";
|
|
10
8
|
import { generateSecureToken } from "openclaw/plugin-sdk/secure-random-runtime";
|
|
11
9
|
import { fetchWithSsrFGuard, isBlockedHostnameOrIp, resolvePinnedHostnameWithPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
12
|
-
//#region extensions/codex/src/app-server/inference-
|
|
13
|
-
const MAX_BODY_BYTES = 33554432;
|
|
14
|
-
function createUploadAdmission() {
|
|
15
|
-
const permits = createPermitPool(16);
|
|
16
|
-
let outstanding = 0;
|
|
17
|
-
let queuedBytes = 0;
|
|
18
|
-
return async (signal, deadlineAtMs, bytes = 0) => {
|
|
19
|
-
const queued = outstanding >= 16;
|
|
20
|
-
if (outstanding >= 32 || queued && queuedBytes + bytes > 33554432) return null;
|
|
21
|
-
outstanding++;
|
|
22
|
-
if (queued) queuedBytes += bytes;
|
|
23
|
-
const releasePermit = await permits.acquire({
|
|
24
|
-
signal,
|
|
25
|
-
deadlineAtMs
|
|
26
|
-
});
|
|
27
|
-
if (queued) queuedBytes -= bytes;
|
|
28
|
-
let released = false;
|
|
29
|
-
const release = () => {
|
|
30
|
-
if (released) return;
|
|
31
|
-
released = true;
|
|
32
|
-
outstanding--;
|
|
33
|
-
releasePermit?.();
|
|
34
|
-
};
|
|
35
|
-
if (!releasePermit || signal.aborted) {
|
|
36
|
-
release();
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
return release;
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
function createUploadBody(bytes, signal, release) {
|
|
43
|
-
const length = bytes.length;
|
|
44
|
-
const chunkSize = getDefaultHighWaterMark(false);
|
|
45
|
-
let remaining = bytes;
|
|
46
|
-
let offset = 0;
|
|
47
|
-
const settle = () => {
|
|
48
|
-
remaining = void 0;
|
|
49
|
-
signal.removeEventListener("abort", settle);
|
|
50
|
-
release();
|
|
51
|
-
};
|
|
52
|
-
signal.addEventListener("abort", settle, { once: true });
|
|
53
|
-
if (signal.aborted) settle();
|
|
54
|
-
return {
|
|
55
|
-
body: new ReadableStream({
|
|
56
|
-
pull(controller) {
|
|
57
|
-
signal.throwIfAborted();
|
|
58
|
-
if (!remaining || offset === length) {
|
|
59
|
-
settle();
|
|
60
|
-
controller.close();
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
const end = Math.min(offset + chunkSize, length);
|
|
64
|
-
controller.enqueue(Uint8Array.from(remaining.subarray(offset, end)));
|
|
65
|
-
offset = end;
|
|
66
|
-
},
|
|
67
|
-
cancel: settle
|
|
68
|
-
}, { highWaterMark: 0 }),
|
|
69
|
-
length,
|
|
70
|
-
settle
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
//#endregion
|
|
74
|
-
//#region extensions/codex/src/app-server/inference-proxy.ts
|
|
75
|
-
const MAX_ERROR_BODY_BYTES = 1048576;
|
|
76
|
-
const MAX_WEBSOCKETS = 64;
|
|
77
|
-
const MAX_RESIDENTS = 80;
|
|
78
|
-
const REQUEST_TIMEOUT_MS = 3e4;
|
|
79
|
-
const HANDSHAKE_TIMEOUT_MS = 1e4;
|
|
80
|
-
const IDLE_WEBSOCKET_MS = 6e4;
|
|
10
|
+
//#region extensions/codex/src/app-server/inference-proxy-http.ts
|
|
81
11
|
const OVERLOADED = "Codex inference relay is busy; retry on a fresh connection.";
|
|
82
12
|
const OVERLOAD_HEADERS = {
|
|
83
13
|
"content-type": "application/json",
|
|
@@ -93,8 +23,6 @@ const OVERLOAD_BODY = JSON.stringify({
|
|
|
93
23
|
},
|
|
94
24
|
headers: { "retry-after": "1" }
|
|
95
25
|
});
|
|
96
|
-
const compress = promisify(zstdCompress);
|
|
97
|
-
const decompress = promisify(zstdDecompress);
|
|
98
26
|
const HOP_HEADERS = /* @__PURE__ */ new Set([
|
|
99
27
|
"connection",
|
|
100
28
|
"keep-alive",
|
|
@@ -107,21 +35,47 @@ const HOP_HEADERS = /* @__PURE__ */ new Set([
|
|
|
107
35
|
"host",
|
|
108
36
|
"content-length"
|
|
109
37
|
]);
|
|
110
|
-
|
|
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;
|
|
111
63
|
/** Private, fixed-destination relay. No upstream credentials or model content are retained. */
|
|
112
64
|
async function createCodexInferenceProxy(params) {
|
|
113
65
|
const upstream = new URL(params.upstream);
|
|
114
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");
|
|
115
68
|
const lifetime = new AbortController();
|
|
116
69
|
const assertCurrent = () => {
|
|
117
70
|
lifetime.signal.throwIfAborted();
|
|
118
71
|
params.assertCurrent();
|
|
119
72
|
};
|
|
120
73
|
const context = createCodexInferenceContext(assertCurrent);
|
|
74
|
+
const upstreamPath = upstream.pathname.replace(/\/+$/, "");
|
|
121
75
|
const pathPrefix = "/" + generateSecureToken({
|
|
122
76
|
bytes: 32,
|
|
123
77
|
redact: true
|
|
124
|
-
}) +
|
|
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" : "");
|
|
125
79
|
const acquireUpload = createUploadAdmission();
|
|
126
80
|
const connections = /* @__PURE__ */ new Set();
|
|
127
81
|
const idleConnections = /* @__PURE__ */ new Set();
|
|
@@ -193,52 +147,27 @@ async function createCodexInferenceProxy(params) {
|
|
|
193
147
|
});
|
|
194
148
|
const resolveTarget = (request) => {
|
|
195
149
|
assertCurrent();
|
|
196
|
-
if (request.headers.origin || !request.url?.startsWith(pathPrefix + "/") || isBlockedHostnameOrIp(upstream.hostname)) throw new Error(
|
|
150
|
+
if (request.headers.origin || !request.url?.startsWith(pathPrefix + "/") || isBlockedHostnameOrIp(upstream.hostname)) throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
|
|
197
151
|
const suffix = request.url.slice(pathPrefix.length);
|
|
198
|
-
|
|
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);
|
|
199
154
|
const target = new URL(upstream);
|
|
200
155
|
const incoming = new URL(suffix, "http://localhost");
|
|
201
|
-
|
|
156
|
+
if (params.oauth && (incoming.pathname !== "/responses" || incoming.search)) throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
|
|
157
|
+
target.pathname = upstreamPath + incoming.pathname;
|
|
202
158
|
for (const [key, value] of incoming.searchParams) target.searchParams.append(key, value);
|
|
203
159
|
return {
|
|
204
160
|
target,
|
|
161
|
+
path: incoming.pathname,
|
|
205
162
|
sampling: incoming.pathname === "/responses"
|
|
206
163
|
};
|
|
207
164
|
};
|
|
208
|
-
const prepare = (
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
};
|
|
215
|
-
const value = JSON.parse(bytes.toString("utf8"));
|
|
216
|
-
if (!isJsonObject(value)) throw new Error(FAILURE);
|
|
217
|
-
const prepared = context.prepare(value);
|
|
218
|
-
const rewritten = Buffer.from(JSON.stringify(prepared.body));
|
|
219
|
-
if (rewritten.length > 33554432) throw new Error(FAILURE);
|
|
220
|
-
return {
|
|
221
|
-
bytes: rewritten,
|
|
222
|
-
assertCurrent: prepared.assertCurrent,
|
|
223
|
-
signal: prepared.signal
|
|
224
|
-
};
|
|
225
|
-
};
|
|
226
|
-
const prepareHttp = async (req, sampling, signal, release) => {
|
|
227
|
-
const wire = await readProxyBody(req, MAX_BODY_BYTES);
|
|
228
|
-
const encoding = req.headers["content-encoding"];
|
|
229
|
-
if (encoding && encoding !== "identity" && encoding !== "zstd") throw new Error(FAILURE);
|
|
230
|
-
const decoded = encoding === "zstd" ? await decompress(wire, { maxOutputLength: MAX_BODY_BYTES }) : wire;
|
|
231
|
-
signal.throwIfAborted();
|
|
232
|
-
const prepared = prepare(decoded, sampling);
|
|
233
|
-
const body = encoding === "zstd" ? await compress(prepared.bytes) : prepared.bytes;
|
|
234
|
-
prepared.assertCurrent();
|
|
235
|
-
const requestSignal = AbortSignal.any([signal, ...prepared.signal ? [prepared.signal] : []]);
|
|
236
|
-
return {
|
|
237
|
-
...createUploadBody(body, requestSignal, release),
|
|
238
|
-
assertCurrent: prepared.assertCurrent,
|
|
239
|
-
signal: requestSignal
|
|
240
|
-
};
|
|
241
|
-
};
|
|
165
|
+
const { prepare, prepareHttp } = createCodexInferenceDispatch({
|
|
166
|
+
context,
|
|
167
|
+
assertCurrent,
|
|
168
|
+
bindModelExecution: params.bindModelExecution,
|
|
169
|
+
requireAdmission: Boolean(params.oauth)
|
|
170
|
+
});
|
|
242
171
|
const server = createServer((req, res) => {
|
|
243
172
|
const socket = req.socket;
|
|
244
173
|
res.setHeader("Connection", "close");
|
|
@@ -254,8 +183,8 @@ async function createCodexInferenceProxy(params) {
|
|
|
254
183
|
res.once("close", abort);
|
|
255
184
|
(async () => {
|
|
256
185
|
try {
|
|
257
|
-
const { target, sampling } = resolveTarget(req);
|
|
258
|
-
if (req.method !== "POST") throw new Error(
|
|
186
|
+
const { target, sampling, path } = resolveTarget(req);
|
|
187
|
+
if (req.method !== "POST") throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
|
|
259
188
|
resident = reserveResident(socket, signal, deadlineAtMs);
|
|
260
189
|
const admitted = resident && await resident.ready;
|
|
261
190
|
signal.throwIfAborted();
|
|
@@ -271,43 +200,78 @@ async function createCodexInferenceProxy(params) {
|
|
|
271
200
|
res.writeHead(503, OVERLOAD_HEADERS).end(OVERLOAD_BODY);
|
|
272
201
|
return;
|
|
273
202
|
}
|
|
274
|
-
upload = await prepareHttp(req, sampling, signal, releasePermit);
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
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 = {
|
|
278
208
|
...relayHeaders(req.headers),
|
|
279
209
|
"content-length": String(upload.length)
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
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);
|
|
296
256
|
upload.assertCurrent();
|
|
297
257
|
const headers = Object.fromEntries(guarded.response.headers);
|
|
298
258
|
delete headers["content-encoding"];
|
|
299
259
|
res.writeHead(guarded.response.status, relayHeaders(headers));
|
|
300
260
|
if (!guarded.response.body) res.end();
|
|
301
261
|
else await guarded.response.body.pipeTo(Writable.toWeb(res), { signal: upload.signal });
|
|
302
|
-
} catch {
|
|
303
|
-
if (!res.headersSent && !res.destroyed)
|
|
304
|
-
|
|
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();
|
|
305
268
|
} finally {
|
|
306
269
|
upload?.settle();
|
|
307
270
|
releasePermit?.();
|
|
308
271
|
req.off("aborted", abort);
|
|
309
272
|
res.off("close", abort);
|
|
310
273
|
await guarded?.release().catch(() => void 0);
|
|
274
|
+
upload?.releaseModelExecution();
|
|
311
275
|
resident?.finish();
|
|
312
276
|
}
|
|
313
277
|
})();
|
|
@@ -333,7 +297,7 @@ async function createCodexInferenceProxy(params) {
|
|
|
333
297
|
let idleTimer;
|
|
334
298
|
let handshakeTimer;
|
|
335
299
|
let closing = false;
|
|
336
|
-
const
|
|
300
|
+
const finish = (status) => {
|
|
337
301
|
if (closing) return;
|
|
338
302
|
closing = true;
|
|
339
303
|
if (idleConnections.has(close)) resident?.retireIdle();
|
|
@@ -346,16 +310,26 @@ async function createCodexInferenceProxy(params) {
|
|
|
346
310
|
remote?.terminate();
|
|
347
311
|
local?.terminate();
|
|
348
312
|
proxyAgent?.destroy();
|
|
349
|
-
socket.
|
|
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();
|
|
350
321
|
setupSettled.then(() => upstreamClosed).then(() => {
|
|
351
322
|
releasePermit?.();
|
|
352
323
|
releasePermit = null;
|
|
353
324
|
resident?.finish();
|
|
354
325
|
});
|
|
355
326
|
};
|
|
327
|
+
const close = () => finish();
|
|
328
|
+
const failHandshake = () => finish(Date.now() >= deadlineAtMs ? 504 : 502);
|
|
356
329
|
try {
|
|
357
|
-
const { target, sampling } = resolveTarget(req);
|
|
358
|
-
if (
|
|
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);
|
|
359
333
|
if (connections.size >= MAX_WEBSOCKETS) idleConnections.values().next().value?.();
|
|
360
334
|
if (connections.size >= MAX_WEBSOCKETS) {
|
|
361
335
|
rejectBusyUpgrade(socket);
|
|
@@ -381,12 +355,12 @@ async function createCodexInferenceProxy(params) {
|
|
|
381
355
|
rejectBusyUpgrade(socket);
|
|
382
356
|
return;
|
|
383
357
|
}
|
|
384
|
-
handshakeTimer = setTimeout(
|
|
358
|
+
handshakeTimer = setTimeout(() => finish(504), Math.max(1, deadlineAtMs - Date.now()));
|
|
385
359
|
handshakeTimer.unref();
|
|
386
360
|
const assertHandshakeCurrent = () => {
|
|
387
361
|
assertCurrent();
|
|
388
362
|
signal.throwIfAborted();
|
|
389
|
-
if (Date.now() >= deadlineAtMs) throw new Error(
|
|
363
|
+
if (Date.now() >= deadlineAtMs) throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
|
|
390
364
|
};
|
|
391
365
|
proxyAgent = createNodeProxyAgent({
|
|
392
366
|
mode: "env",
|
|
@@ -422,20 +396,20 @@ async function createCodexInferenceProxy(params) {
|
|
|
422
396
|
remote.once("upgrade", (response) => {
|
|
423
397
|
handshakeHeaders.set(req, relayHeaders(response.headers));
|
|
424
398
|
});
|
|
425
|
-
remote.once("error",
|
|
426
|
-
remote.once("close",
|
|
399
|
+
remote.once("error", failHandshake);
|
|
400
|
+
remote.once("close", failHandshake);
|
|
427
401
|
remote.once("unexpected-response", (_request, response) => {
|
|
428
402
|
(async () => {
|
|
429
403
|
try {
|
|
430
404
|
const body = await readProxyBody(response, MAX_ERROR_BODY_BYTES);
|
|
431
|
-
|
|
432
|
-
|
|
405
|
+
assertHandshakeCurrent();
|
|
406
|
+
clearTimeout(handshakeTimer);
|
|
433
407
|
const failureHeaders = Object.entries(relayHeaders(response.headers)).map(([key, value]) => key + ": " + value);
|
|
434
408
|
failureHeaders.push("Connection: close", "Content-Length: " + body.length);
|
|
435
409
|
const status = "HTTP/1.1 " + response.statusCode + " " + (response.statusMessage ?? "Upstream refused");
|
|
436
410
|
socket.end(Buffer.concat([Buffer.from(status + "\r\n" + failureHeaders.join("\r\n") + "\r\n\r\n"), body]), close);
|
|
437
411
|
} catch {
|
|
438
|
-
|
|
412
|
+
failHandshake();
|
|
439
413
|
}
|
|
440
414
|
})();
|
|
441
415
|
});
|
|
@@ -449,6 +423,7 @@ async function createCodexInferenceProxy(params) {
|
|
|
449
423
|
accepted.once("error", close);
|
|
450
424
|
accepted.once("close", close);
|
|
451
425
|
let releaseFrame = () => {};
|
|
426
|
+
let settleFrame = () => {};
|
|
452
427
|
const idle = (reclaimable = true) => {
|
|
453
428
|
framePending = false;
|
|
454
429
|
idleConnections.delete(close);
|
|
@@ -472,7 +447,7 @@ async function createCodexInferenceProxy(params) {
|
|
|
472
447
|
accepted.send(OVERLOAD_BODY, { binary: false }, close);
|
|
473
448
|
return;
|
|
474
449
|
}
|
|
475
|
-
if (!remote || remote.readyState !== WebSocket.OPEN || remote.bufferedAmount + prepared.bytes.length > 33554432) throw new Error(
|
|
450
|
+
if (!remote || remote.readyState !== WebSocket.OPEN || remote.bufferedAmount + prepared.bytes.length > 33554432) throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
|
|
476
451
|
const release = releaseUpload;
|
|
477
452
|
remote.send(prepared.bytes, { binary: false }, (error) => {
|
|
478
453
|
release();
|
|
@@ -484,43 +459,67 @@ async function createCodexInferenceProxy(params) {
|
|
|
484
459
|
}
|
|
485
460
|
};
|
|
486
461
|
accepted.on("message", (data, binary) => {
|
|
487
|
-
|
|
488
|
-
if (binary) throw new Error(FAILURE);
|
|
489
|
-
const prepared = prepare(rawBytes(data), true);
|
|
490
|
-
prepared.assertCurrent();
|
|
491
|
-
if (framePending) throw new Error(FAILURE);
|
|
492
|
-
framePending = true;
|
|
493
|
-
clearTimeout(idleTimer);
|
|
494
|
-
idleConnections.delete(close);
|
|
495
|
-
releaseFrame();
|
|
496
|
-
const onAbort = () => close();
|
|
497
|
-
const frameSignal = prepared.signal;
|
|
498
|
-
frameSignal?.addEventListener("abort", onAbort, { once: true });
|
|
499
|
-
releaseFrame = () => frameSignal?.removeEventListener("abort", onAbort);
|
|
500
|
-
forward(prepared);
|
|
501
|
-
} catch {
|
|
462
|
+
if (framePending) {
|
|
502
463
|
close();
|
|
464
|
+
return;
|
|
503
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
|
+
})();
|
|
504
498
|
});
|
|
505
499
|
accepted.once("close", () => releaseFrame());
|
|
506
500
|
remote.on("message", (data, binary) => {
|
|
507
|
-
if (accepted.readyState !== WebSocket.OPEN || accepted.bufferedAmount +
|
|
501
|
+
if (accepted.readyState !== WebSocket.OPEN || accepted.bufferedAmount + readProxyWebSocketBody(data).length > 33554432) {
|
|
508
502
|
close();
|
|
509
503
|
return;
|
|
510
504
|
}
|
|
511
|
-
const terminal = !binary && isTerminalResponse(
|
|
505
|
+
const terminal = !binary && isTerminalResponse(readProxyWebSocketBody(data));
|
|
506
|
+
const releaseCompletedFrame = terminal ? settleFrame : void 0;
|
|
512
507
|
accepted.send(data, { binary }, (error) => {
|
|
513
508
|
if (error) close();
|
|
514
|
-
else if (terminal && connections.has(close))
|
|
509
|
+
else if (terminal && connections.has(close)) {
|
|
510
|
+
releaseCompletedFrame?.();
|
|
511
|
+
idle();
|
|
512
|
+
}
|
|
515
513
|
});
|
|
516
514
|
});
|
|
517
515
|
});
|
|
518
516
|
} catch {
|
|
519
|
-
|
|
517
|
+
failHandshake();
|
|
520
518
|
}
|
|
521
519
|
});
|
|
522
520
|
} catch {
|
|
523
|
-
close();
|
|
521
|
+
if (connections.has(close)) failHandshake();
|
|
522
|
+
else close();
|
|
524
523
|
} finally {
|
|
525
524
|
finishSetup();
|
|
526
525
|
}
|
|
@@ -545,7 +544,7 @@ async function createCodexInferenceProxy(params) {
|
|
|
545
544
|
assertCurrent();
|
|
546
545
|
server.on("error", close);
|
|
547
546
|
const address = server.address();
|
|
548
|
-
if (!address || typeof address === "string") throw new Error(
|
|
547
|
+
if (!address || typeof address === "string") throw new Error(CODEX_INFERENCE_TRANSPORT_FAILURE);
|
|
549
548
|
return {
|
|
550
549
|
context,
|
|
551
550
|
upstream: upstream.toString(),
|
|
@@ -558,44 +557,5 @@ async function createCodexInferenceProxy(params) {
|
|
|
558
557
|
throw error;
|
|
559
558
|
}
|
|
560
559
|
}
|
|
561
|
-
function rejectBusyUpgrade(socket) {
|
|
562
|
-
rejectWebSocketUpgrade(socket, {
|
|
563
|
-
status: 503,
|
|
564
|
-
headers: { "Retry-After": "1" },
|
|
565
|
-
body: {
|
|
566
|
-
contentType: "application/json",
|
|
567
|
-
text: OVERLOAD_BODY
|
|
568
|
-
}
|
|
569
|
-
});
|
|
570
|
-
}
|
|
571
|
-
function isTerminalResponse(bytes) {
|
|
572
|
-
try {
|
|
573
|
-
const event = JSON.parse(bytes.toString("utf8"));
|
|
574
|
-
return isJsonObject(event) && (event.type === "response.failed" || event.type === "response.incomplete" || event.type === "response.completed" && isJsonObject(event.response) && typeof event.response.id === "string");
|
|
575
|
-
} catch {
|
|
576
|
-
return false;
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
async function readProxyBody(stream, maxBytes) {
|
|
580
|
-
const chunks = [];
|
|
581
|
-
let size = 0;
|
|
582
|
-
for await (const chunk of stream) {
|
|
583
|
-
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
584
|
-
size += bytes.length;
|
|
585
|
-
if (size > maxBytes) throw new Error(FAILURE);
|
|
586
|
-
chunks.push(bytes);
|
|
587
|
-
}
|
|
588
|
-
return Buffer.concat(chunks);
|
|
589
|
-
}
|
|
590
|
-
function rawBytes(data) {
|
|
591
|
-
return Array.isArray(data) ? Buffer.concat(data) : Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
592
|
-
}
|
|
593
|
-
function relayHeaders(input) {
|
|
594
|
-
const excluded = new Set(HOP_HEADERS);
|
|
595
|
-
for (const token of (input.connection ?? "").split(",")) excluded.add(token.trim().toLowerCase());
|
|
596
|
-
const output = {};
|
|
597
|
-
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;
|
|
598
|
-
return output;
|
|
599
|
-
}
|
|
600
560
|
//#endregion
|
|
601
|
-
export { createCodexInferenceProxy };
|
|
561
|
+
export { CodexInferenceAuthorizationError, createCodexInferenceProxy };
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { d as readCodexPluginConfig } from "./config-parsing-
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import "./
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { a as createAttributedCodexAssistantMessage } from "./event-projector-assistant-message-BsruvNrH.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";
|
|
10
9
|
//#region extensions/codex/src/app-server/isolated-completion.ts
|
|
11
10
|
/** Runs prompt-only Codex inference on an ephemeral, ring-zero native thread. */
|
|
12
11
|
async function runCodexIsolatedCompletion(params, options) {
|
|
@@ -15,8 +14,6 @@ async function runCodexIsolatedCompletion(params, options) {
|
|
|
15
14
|
if (authorization.owner !== "harness") throw new Error("Codex native isolated completion requires harness-owned authorization.");
|
|
16
15
|
const pluginConfig = readCodexPluginConfig(options.pluginConfig);
|
|
17
16
|
const homeScope = resolveCodexAppServerHomeScope({ appServer: pluginConfig.appServer });
|
|
18
|
-
const { start } = resolveCodexAppServerRuntimeOptions({ pluginConfig: options.pluginConfig });
|
|
19
|
-
const privateStdio = start.transport === "stdio" && homeScope === "agent" && !isCodexAppServerProxyLaunch(start.args);
|
|
20
17
|
const authRequirement = authorization.plan.modelRoute?.authRequirement;
|
|
21
18
|
const authHandoff = await resolveCodexAppServerPreparedAuthHandoff({
|
|
22
19
|
authRequirement,
|
|
@@ -53,7 +50,7 @@ async function runCodexIsolatedCompletion(params, options) {
|
|
|
53
50
|
text_elements: []
|
|
54
51
|
}],
|
|
55
52
|
requiredModalities: ["text"],
|
|
56
|
-
isolation:
|
|
53
|
+
isolation: resolveCodexBoundedTurnIsolation(options),
|
|
57
54
|
requireNoExternalCapabilities: true,
|
|
58
55
|
allowEmptyText: params.outputTextPolicy === "strict-visible"
|
|
59
56
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as __exportAll } from "./
|
|
1
|
+
import { t as __exportAll } from "./session-binding-sidecars-jo6H8dFr.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { constants, existsSync, realpathSync } from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
@@ -19,7 +19,10 @@ const MACOS_DESKTOP_CODEX_APP_PATH_CANDIDATES = [{
|
|
|
19
19
|
appServerCommandPath: "/Applications/Codex.app/Contents/Resources/codex",
|
|
20
20
|
bundledMarketplacePath: "/Applications/Codex.app/Contents/Resources/plugins/openai-bundled",
|
|
21
21
|
computerUseServiceAppPaths: ["/Applications/Codex.app/Contents/Resources/plugins/openai-bundled/plugins/computer-use/Codex Computer Use.app", "/Applications/Codex.app/Contents/Resources/cua_node/lib/node_modules/@oai/sky/Codex Computer Use.app"]
|
|
22
|
-
}]
|
|
22
|
+
}].flatMap((candidate) => [{
|
|
23
|
+
...candidate,
|
|
24
|
+
appServerCommandPath: path.join(candidate.appBundlePath, "Contents", "Resources", "codex-cli", "CodexCLI.app", "Contents", "MacOS", "codex")
|
|
25
|
+
}, candidate]);
|
|
23
26
|
function resolveMacOSDesktopCodexAppPathCandidates(platform = process.platform) {
|
|
24
27
|
return platform === "darwin" ? MACOS_DESKTOP_CODEX_APP_PATH_CANDIDATES : [];
|
|
25
28
|
}
|
|
@@ -27,7 +30,7 @@ function resolveMacOSDesktopCodexAppServerCommandCandidates(platform = process.p
|
|
|
27
30
|
return resolveMacOSDesktopCodexAppPathCandidates(platform).map((candidate) => candidate.appServerCommandPath);
|
|
28
31
|
}
|
|
29
32
|
function resolveMacOSDesktopCodexBundledMarketplaceCandidates(platform = process.platform) {
|
|
30
|
-
return resolveMacOSDesktopCodexAppPathCandidates(platform).map((candidate) => candidate.bundledMarketplacePath);
|
|
33
|
+
return [...new Set(resolveMacOSDesktopCodexAppPathCandidates(platform).map((candidate) => candidate.bundledMarketplacePath))];
|
|
31
34
|
}
|
|
32
35
|
function resolveMacOSDesktopCodexComputerUseServiceAppCandidates(platform = process.platform, appServerCommand) {
|
|
33
36
|
if (platform !== "darwin") return [];
|
|
@@ -43,14 +46,10 @@ function resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath(params = {}
|
|
|
43
46
|
}
|
|
44
47
|
//#endregion
|
|
45
48
|
//#region extensions/codex/src/app-server/version.ts
|
|
46
|
-
/**
|
|
47
|
-
* Version and package pins for the managed Codex app-server runtime.
|
|
48
|
-
*/
|
|
49
49
|
/** Exact Codex app-server version shipped by the OpenClaw Codex bridge. */
|
|
50
|
-
const CODEX_APP_SERVER_VERSION = "0.
|
|
50
|
+
const CODEX_APP_SERVER_VERSION = "0.158.0";
|
|
51
51
|
/** Inclusive runtime compatibility floor for external app-server binaries. */
|
|
52
52
|
const MIN_SUPPORTED_CODEX_APP_SERVER_VERSION = "0.149.0";
|
|
53
|
-
/** npm package name for the managed Codex app-server binary. */
|
|
54
53
|
const MANAGED_CODEX_APP_SERVER_PACKAGE = "@openai/codex";
|
|
55
54
|
//#endregion
|
|
56
55
|
//#region extensions/codex/src/app-server/managed-binary.ts
|
|
@@ -117,7 +116,7 @@ function isManagedCodexDesktopCommand(command, platform = process.platform) {
|
|
|
117
116
|
return platform === "darwin" && resolveMacOSDesktopCodexAppServerCommandCandidates(platform).some((candidate) => candidate === command);
|
|
118
117
|
}
|
|
119
118
|
function resolveManagedCodexPackageRootForCommand(command, platform) {
|
|
120
|
-
const pathApi =
|
|
119
|
+
const pathApi = platform === "win32" ? path.win32 : path.posix;
|
|
121
120
|
const commandPaths = [command];
|
|
122
121
|
try {
|
|
123
122
|
commandPaths.unshift(realpathSync(command));
|
|
@@ -181,9 +180,6 @@ function resolveManagedCodexPackageEntrypoint(pluginRoot) {
|
|
|
181
180
|
return;
|
|
182
181
|
}
|
|
183
182
|
}
|
|
184
|
-
function pathForPlatform(platform) {
|
|
185
|
-
return platform === "win32" ? path.win32 : path.posix;
|
|
186
|
-
}
|
|
187
183
|
async function findManagedCodexAppServerCommandPaths(params) {
|
|
188
184
|
const commandPaths = [];
|
|
189
185
|
for (const commandPath of params.candidateCommandPaths) if (await params.pathExists(commandPath, params.platform)) commandPaths.push(commandPath);
|