@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
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
|
|
2
|
+
import { n as readCodexInferenceMetadata } from "./inference-metadata-CgIf7sOx.mjs";
|
|
3
|
+
import { promisify } from "node:util";
|
|
4
|
+
import { isUtf8 } from "node:buffer";
|
|
5
|
+
import { zstdCompress, zstdDecompress } from "node:zlib";
|
|
6
|
+
import { createPermitPool } from "openclaw/plugin-sdk/concurrency-runtime";
|
|
7
|
+
import { getDefaultHighWaterMark } from "node:stream";
|
|
8
|
+
//#region extensions/codex/src/app-server/inference-upload.ts
|
|
9
|
+
const MAX_BODY_BYTES = 33554432;
|
|
10
|
+
function createUploadAdmission() {
|
|
11
|
+
const permits = createPermitPool(16);
|
|
12
|
+
let outstanding = 0;
|
|
13
|
+
let queuedBytes = 0;
|
|
14
|
+
return async (signal, deadlineAtMs, bytes = 0) => {
|
|
15
|
+
const queued = outstanding >= 16;
|
|
16
|
+
if (outstanding >= 32 || queued && queuedBytes + bytes > 33554432) return null;
|
|
17
|
+
outstanding++;
|
|
18
|
+
if (queued) queuedBytes += bytes;
|
|
19
|
+
const releasePermit = await permits.acquire({
|
|
20
|
+
signal,
|
|
21
|
+
deadlineAtMs
|
|
22
|
+
});
|
|
23
|
+
if (queued) queuedBytes -= bytes;
|
|
24
|
+
let released = false;
|
|
25
|
+
const release = () => {
|
|
26
|
+
if (released) return;
|
|
27
|
+
released = true;
|
|
28
|
+
outstanding--;
|
|
29
|
+
releasePermit?.();
|
|
30
|
+
};
|
|
31
|
+
if (!releasePermit || signal.aborted) {
|
|
32
|
+
release();
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return release;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function createUploadBody(bytes, signal, release) {
|
|
39
|
+
const length = bytes.length;
|
|
40
|
+
const chunkSize = getDefaultHighWaterMark(false);
|
|
41
|
+
let remaining = bytes;
|
|
42
|
+
let offset = 0;
|
|
43
|
+
const settle = () => {
|
|
44
|
+
remaining = void 0;
|
|
45
|
+
signal.removeEventListener("abort", settle);
|
|
46
|
+
release();
|
|
47
|
+
};
|
|
48
|
+
signal.addEventListener("abort", settle, { once: true });
|
|
49
|
+
if (signal.aborted) settle();
|
|
50
|
+
return {
|
|
51
|
+
body: new ReadableStream({
|
|
52
|
+
pull(controller) {
|
|
53
|
+
signal.throwIfAborted();
|
|
54
|
+
if (!remaining || offset === length) {
|
|
55
|
+
settle();
|
|
56
|
+
controller.close();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const end = Math.min(offset + chunkSize, length);
|
|
60
|
+
controller.enqueue(Uint8Array.from(remaining.subarray(offset, end)));
|
|
61
|
+
offset = end;
|
|
62
|
+
},
|
|
63
|
+
cancel: settle
|
|
64
|
+
}, { highWaterMark: 0 }),
|
|
65
|
+
length,
|
|
66
|
+
settle
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Retain one bounded upload under its original permit until OAuth accepts it or retries once. */
|
|
70
|
+
function createRetryableUploadBody(bytes, signal, release) {
|
|
71
|
+
let replay = bytes;
|
|
72
|
+
let firstActive = true;
|
|
73
|
+
let uploaded = false;
|
|
74
|
+
let active = createUploadBody(bytes, signal, () => {
|
|
75
|
+
uploaded = true;
|
|
76
|
+
if (firstActive && !replay) release();
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
body: active.body,
|
|
80
|
+
length: active.length,
|
|
81
|
+
commit() {
|
|
82
|
+
replay = void 0;
|
|
83
|
+
if (firstActive && uploaded) release();
|
|
84
|
+
},
|
|
85
|
+
retry() {
|
|
86
|
+
signal.throwIfAborted();
|
|
87
|
+
if (!replay) throw new Error("Codex inference upload cannot be replayed");
|
|
88
|
+
firstActive = false;
|
|
89
|
+
active.settle();
|
|
90
|
+
active = createUploadBody(replay, signal, release);
|
|
91
|
+
replay = void 0;
|
|
92
|
+
return active.body;
|
|
93
|
+
},
|
|
94
|
+
settle() {
|
|
95
|
+
replay = void 0;
|
|
96
|
+
active.settle();
|
|
97
|
+
release();
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region extensions/codex/src/app-server/inference-dispatch.ts
|
|
103
|
+
const CODEX_INFERENCE_TRANSPORT_FAILURE = "Codex parent-local inference transport failed; retry on a fresh connection.";
|
|
104
|
+
const FAILURE = CODEX_INFERENCE_TRANSPORT_FAILURE;
|
|
105
|
+
const compress = promisify(zstdCompress);
|
|
106
|
+
const decompress = promisify(zstdDecompress);
|
|
107
|
+
/** Only host-owned authorization failures may cross the private transport boundary. */
|
|
108
|
+
var CodexInferenceAuthorizationError = class extends Error {
|
|
109
|
+
constructor(reason) {
|
|
110
|
+
super(reason === "model" ? "Your operator role cannot use this model. Choose an allowed model or ask a gateway administrator to update your role's model policy." : "Codex cannot verify the owner of this model request. Start a fresh request before retrying.");
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
function authorizationFailure(error) {
|
|
114
|
+
if (!(error instanceof CodexInferenceAuthorizationError)) return;
|
|
115
|
+
return JSON.stringify({
|
|
116
|
+
type: "error",
|
|
117
|
+
status: 403,
|
|
118
|
+
error: {
|
|
119
|
+
type: "invalid_request_error",
|
|
120
|
+
code: "model_permission_denied",
|
|
121
|
+
message: error.message
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/** The route supplies its selected provider; native custody supplies the execution's source. */
|
|
126
|
+
function createCodexInferenceModelBinding(params) {
|
|
127
|
+
const { assertCurrent: assertClient, provider } = params;
|
|
128
|
+
const refuseOwner = (error, signal) => {
|
|
129
|
+
signal.throwIfAborted();
|
|
130
|
+
assertClient();
|
|
131
|
+
throw error instanceof CodexInferenceAuthorizationError ? error : new CodexInferenceAuthorizationError("owner");
|
|
132
|
+
};
|
|
133
|
+
return async ({ path, body, metadata, signal, transport }) => {
|
|
134
|
+
assertClient();
|
|
135
|
+
signal.throwIfAborted();
|
|
136
|
+
if (typeof body.model !== "string" || !body.model.trim() || transport === "websocket" && (body.type !== "response.create" || ![
|
|
137
|
+
"/responses",
|
|
138
|
+
"/guardian",
|
|
139
|
+
"/guardian-classifier"
|
|
140
|
+
].includes(path)) || ![
|
|
141
|
+
"/responses",
|
|
142
|
+
"/responses/compact",
|
|
143
|
+
"/alpha/search",
|
|
144
|
+
"/images/generations",
|
|
145
|
+
"/images/edits",
|
|
146
|
+
"/guardian",
|
|
147
|
+
"/guardian-classifier"
|
|
148
|
+
].includes(path)) throw new CodexInferenceAuthorizationError("owner");
|
|
149
|
+
const reviewer = metadata.subagent === "guardian" && metadata.threadSource === "guardian_review";
|
|
150
|
+
const classifier = metadata.subagent === "guardian" && metadata.threadSource === "guardian_classifier";
|
|
151
|
+
if (path === "/guardian" && !reviewer || path === "/guardian-classifier" && !classifier || path === "/responses/compact" && metadata.requestKind !== "compaction") throw new CodexInferenceAuthorizationError("owner");
|
|
152
|
+
if (path === "/responses" && metadata.requestKind === "prewarm" && body.generate === false) return {
|
|
153
|
+
assertCurrent: assertClient,
|
|
154
|
+
release: () => {}
|
|
155
|
+
};
|
|
156
|
+
const memory = metadata.threadSource === "memory_consolidation" && (metadata.requestKind === "memory" || metadata.subagent === "memory_consolidation");
|
|
157
|
+
if (memory && params.memoryConfigured() && path === "/responses") return {
|
|
158
|
+
assertCurrent: assertClient,
|
|
159
|
+
release: () => {}
|
|
160
|
+
};
|
|
161
|
+
const parentExecution = reviewer || classifier || metadata.subagent === "review";
|
|
162
|
+
const imageTurnId = metadata.nativeImageTurnId;
|
|
163
|
+
const threadId = imageTurnId ? params.resolveModelThreadId({
|
|
164
|
+
client: params.client,
|
|
165
|
+
turnId: imageTurnId
|
|
166
|
+
}) : parentExecution ? classifier ? metadata.guardianClassifierSourceThreadId : metadata.parentThreadId : metadata.threadId;
|
|
167
|
+
const turnId = imageTurnId ?? (parentExecution ? metadata.parentTurnId : metadata.turnId);
|
|
168
|
+
if (!threadId || !turnId || memory) throw new CodexInferenceAuthorizationError("owner");
|
|
169
|
+
let acquired;
|
|
170
|
+
try {
|
|
171
|
+
acquired = await params.captureModelSource({
|
|
172
|
+
client: params.client,
|
|
173
|
+
threadId,
|
|
174
|
+
turnId,
|
|
175
|
+
...parentExecution ? { rootTurnId: metadata.rootTurnId } : {
|
|
176
|
+
parentThreadId: metadata.parentThreadId,
|
|
177
|
+
parentTurnId: metadata.parentTurnId,
|
|
178
|
+
rootTurnId: metadata.rootTurnId
|
|
179
|
+
},
|
|
180
|
+
signal
|
|
181
|
+
});
|
|
182
|
+
} catch (error) {
|
|
183
|
+
refuseOwner(error, signal);
|
|
184
|
+
}
|
|
185
|
+
if (!acquired) throw new CodexInferenceAuthorizationError("owner");
|
|
186
|
+
const captured = acquired;
|
|
187
|
+
const cancelNativeTurn = () => {
|
|
188
|
+
if (!imageTurnId) captured.cancel();
|
|
189
|
+
};
|
|
190
|
+
let model;
|
|
191
|
+
let releaseAbort = () => {};
|
|
192
|
+
try {
|
|
193
|
+
captured.assertCurrent();
|
|
194
|
+
signal.throwIfAborted();
|
|
195
|
+
assertClient();
|
|
196
|
+
if (reviewer || classifier) {
|
|
197
|
+
if (!captured.nativeReviewRequired) throw new CodexInferenceAuthorizationError("owner");
|
|
198
|
+
} else if (captured.source) {
|
|
199
|
+
const bind = captured.source.bindModelExecution;
|
|
200
|
+
if (!bind) throw new CodexInferenceAuthorizationError("owner");
|
|
201
|
+
try {
|
|
202
|
+
const mapping = captured.modelMapping;
|
|
203
|
+
model = bind(params.modelPolicyEnforced === false ? void 0 : mapping?.nativeModel.provider === provider && mapping.nativeModel.model === body.model ? mapping.authorizedModel : {
|
|
204
|
+
provider,
|
|
205
|
+
model: body.model
|
|
206
|
+
});
|
|
207
|
+
} catch {
|
|
208
|
+
cancelNativeTurn();
|
|
209
|
+
throw new CodexInferenceAuthorizationError("model");
|
|
210
|
+
}
|
|
211
|
+
if (!model) throw new CodexInferenceAuthorizationError("owner");
|
|
212
|
+
const revoke = cancelNativeTurn;
|
|
213
|
+
model?.signal.addEventListener("abort", revoke, { once: true });
|
|
214
|
+
releaseAbort = () => model?.signal.removeEventListener("abort", revoke);
|
|
215
|
+
if (model?.signal.aborted) revoke();
|
|
216
|
+
}
|
|
217
|
+
if (!parentExecution) captured.recordNativeReviewRequirement(metadata.autoReviewEnabled === true || metadata.nodeReplAutoReviewRequired === true);
|
|
218
|
+
const assertExecution = () => {
|
|
219
|
+
assertClient();
|
|
220
|
+
try {
|
|
221
|
+
captured.assertCurrent();
|
|
222
|
+
model?.assertCurrent();
|
|
223
|
+
} catch (error) {
|
|
224
|
+
refuseOwner(error, signal);
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
assertExecution();
|
|
228
|
+
return {
|
|
229
|
+
assertCurrent: assertExecution,
|
|
230
|
+
signal: model?.signal ?? captured.source?.signal,
|
|
231
|
+
release: () => {
|
|
232
|
+
releaseAbort();
|
|
233
|
+
model?.release();
|
|
234
|
+
captured.release();
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
} catch (error) {
|
|
238
|
+
releaseAbort();
|
|
239
|
+
model?.release();
|
|
240
|
+
captured.release();
|
|
241
|
+
return refuseOwner(error, signal);
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
/** One preparation path binds both HTTP requests and reusable WebSocket frames. */
|
|
246
|
+
function createCodexInferenceDispatch(params) {
|
|
247
|
+
const { context, assertCurrent } = params;
|
|
248
|
+
const prepare = async (bytes, sampling, path, headers, signal, transport) => {
|
|
249
|
+
assertCurrent();
|
|
250
|
+
let execution;
|
|
251
|
+
let released = false;
|
|
252
|
+
const release = () => {
|
|
253
|
+
if (!released) {
|
|
254
|
+
released = true;
|
|
255
|
+
execution?.release();
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
try {
|
|
259
|
+
const value = sampling || params.bindModelExecution ? JSON.parse(bytes.toString("utf8")) : void 0;
|
|
260
|
+
if ((sampling || params.bindModelExecution) && !isJsonObject(value)) throw new Error(FAILURE);
|
|
261
|
+
let metadata;
|
|
262
|
+
if (isJsonObject(value)) {
|
|
263
|
+
try {
|
|
264
|
+
metadata = readCodexInferenceMetadata(value, headers, transport, path);
|
|
265
|
+
} catch (error) {
|
|
266
|
+
if (params.bindModelExecution) throw new CodexInferenceAuthorizationError("owner");
|
|
267
|
+
throw error;
|
|
268
|
+
}
|
|
269
|
+
execution = await params.bindModelExecution?.({
|
|
270
|
+
path,
|
|
271
|
+
body: value,
|
|
272
|
+
headers,
|
|
273
|
+
metadata,
|
|
274
|
+
transport,
|
|
275
|
+
signal
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
signal.throwIfAborted();
|
|
279
|
+
const prepared = sampling && isJsonObject(value) ? context.prepare(value, metadata, params.requireAdmission) : void 0;
|
|
280
|
+
const assertPrepared = () => {
|
|
281
|
+
if (released) throw new Error(FAILURE);
|
|
282
|
+
assertCurrent();
|
|
283
|
+
signal.throwIfAborted();
|
|
284
|
+
prepared?.assertCurrent();
|
|
285
|
+
execution?.assertCurrent();
|
|
286
|
+
};
|
|
287
|
+
assertPrepared();
|
|
288
|
+
const rewritten = prepared && (prepared.body !== value || !isUtf8(bytes)) ? Buffer.from(JSON.stringify(prepared.body)) : bytes;
|
|
289
|
+
if (rewritten.length > 33554432) throw new Error(FAILURE);
|
|
290
|
+
return {
|
|
291
|
+
bytes: rewritten,
|
|
292
|
+
assertCurrent: assertPrepared,
|
|
293
|
+
signal: AbortSignal.any([
|
|
294
|
+
signal,
|
|
295
|
+
...prepared?.signal ? [prepared.signal] : [],
|
|
296
|
+
...execution?.signal ? [execution.signal] : []
|
|
297
|
+
]),
|
|
298
|
+
contextSignal: prepared?.signal,
|
|
299
|
+
release
|
|
300
|
+
};
|
|
301
|
+
} catch (error) {
|
|
302
|
+
release();
|
|
303
|
+
throw error;
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
const prepareHttp = async (req, sampling, path, signal, release, retryable = false) => {
|
|
307
|
+
const wire = await readProxyBody(req, MAX_BODY_BYTES);
|
|
308
|
+
const encoding = req.headers["content-encoding"];
|
|
309
|
+
if (encoding && encoding !== "identity" && encoding !== "zstd") throw new Error(FAILURE);
|
|
310
|
+
const decoded = encoding === "zstd" ? await decompress(wire, { maxOutputLength: MAX_BODY_BYTES }) : wire;
|
|
311
|
+
signal.throwIfAborted();
|
|
312
|
+
const prepared = await prepare(decoded, sampling, path, req.headers, signal, "http");
|
|
313
|
+
try {
|
|
314
|
+
const body = prepared.bytes === decoded ? wire : encoding === "zstd" ? await compress(prepared.bytes) : prepared.bytes;
|
|
315
|
+
prepared.assertCurrent();
|
|
316
|
+
return {
|
|
317
|
+
...retryable ? createRetryableUploadBody(body, prepared.signal, release) : {
|
|
318
|
+
...createUploadBody(body, prepared.signal, release),
|
|
319
|
+
retry: void 0,
|
|
320
|
+
commit: void 0
|
|
321
|
+
},
|
|
322
|
+
assertCurrent: prepared.assertCurrent,
|
|
323
|
+
signal: prepared.signal,
|
|
324
|
+
releaseModelExecution: prepared.release
|
|
325
|
+
};
|
|
326
|
+
} catch (error) {
|
|
327
|
+
prepared.release();
|
|
328
|
+
throw error;
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
return {
|
|
332
|
+
prepare,
|
|
333
|
+
prepareHttp
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
async function readProxyBody(stream, maxBytes) {
|
|
337
|
+
const chunks = [];
|
|
338
|
+
let size = 0;
|
|
339
|
+
for await (const chunk of stream) {
|
|
340
|
+
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
341
|
+
size += bytes.length;
|
|
342
|
+
if (size > maxBytes) throw new Error(FAILURE);
|
|
343
|
+
chunks.push(bytes);
|
|
344
|
+
}
|
|
345
|
+
return Buffer.concat(chunks);
|
|
346
|
+
}
|
|
347
|
+
function readProxyWebSocketBody(data) {
|
|
348
|
+
return Array.isArray(data) ? Buffer.concat(data) : Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
349
|
+
}
|
|
350
|
+
function isTerminalResponse(bytes) {
|
|
351
|
+
try {
|
|
352
|
+
const event = JSON.parse(bytes.toString("utf8"));
|
|
353
|
+
return isJsonObject(event) && (event.type === "response.failed" || event.type === "response.incomplete" || event.type === "response.completed" && isJsonObject(event.response) && typeof event.response.id === "string");
|
|
354
|
+
} catch {
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
//#endregion
|
|
359
|
+
export { CODEX_INFERENCE_TRANSPORT_FAILURE, CodexInferenceAuthorizationError, authorizationFailure, createCodexInferenceDispatch, createCodexInferenceModelBinding, isTerminalResponse, createUploadAdmission as n, readProxyBody, readProxyWebSocketBody, MAX_BODY_BYTES as t };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { asBoolean, isRecord, readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
|
+
//#region extensions/codex/src/app-server/inference-metadata.ts
|
|
3
|
+
const MAX_NATIVE_METADATA_BYTES = 1048576;
|
|
4
|
+
const MAX_METADATA_FIELD_BYTES = 256;
|
|
5
|
+
const CODEX_INFERENCE_GENERATION_KEY = "openclaw_inference_generation";
|
|
6
|
+
/** Call only after authenticating the private transport that supplied these carriers. */
|
|
7
|
+
function readCodexInferenceMetadata(body, headers, transport = "http", path) {
|
|
8
|
+
if (transport === "http" && (path === "/images/generations" || path === "/images/edits")) {
|
|
9
|
+
const nativeImageTurnId = readId("image turn", headers?.["x-codex-image-turn-id"]);
|
|
10
|
+
if (!nativeImageTurnId) throw new Error("Codex image inference has no native turn metadata");
|
|
11
|
+
return Object.freeze({ nativeImageTurnId });
|
|
12
|
+
}
|
|
13
|
+
const flat = body.client_metadata;
|
|
14
|
+
if (flat !== void 0 && !isRecord(flat)) throw new Error("Codex inference request has invalid native metadata");
|
|
15
|
+
const nested = readNativeMetadata(flat?.["x-codex-turn-metadata"]);
|
|
16
|
+
const httpHeaders = transport === "http" ? headers : void 0;
|
|
17
|
+
const compatibility = readNativeMetadata(httpHeaders?.["x-codex-turn-metadata"]);
|
|
18
|
+
if (!nested && !compatibility) throw new Error("Codex inference request is missing bounded native metadata");
|
|
19
|
+
const requestKind = reconcileMetadataStrings("request kind", nested?.request_kind, compatibility?.request_kind);
|
|
20
|
+
const generation = readId("parent generation", nested?.[CODEX_INFERENCE_GENERATION_KEY], compatibility?.[CODEX_INFERENCE_GENERATION_KEY]);
|
|
21
|
+
const nativeThreadId = readId("thread", nested?.thread_id, compatibility?.thread_id);
|
|
22
|
+
if (!nativeThreadId && (requestKind === "turn" || requestKind === "prewarm" && !(body.generate === false && generation === void 0))) throw new Error("Codex inference request has no native thread metadata");
|
|
23
|
+
return Object.freeze({
|
|
24
|
+
sessionId: readId("session", flat?.session_id, nested?.session_id, compatibility?.session_id, httpHeaders?.["session-id"]),
|
|
25
|
+
threadId: readId("thread", flat?.thread_id, nativeThreadId, httpHeaders?.["thread-id"]),
|
|
26
|
+
turnId: readId("turn", flat?.turn_id, nested?.turn_id, compatibility?.turn_id),
|
|
27
|
+
parentThreadId: readId("parent thread", flat?.["x-codex-parent-thread-id"], nested?.parent_thread_id, compatibility?.parent_thread_id, httpHeaders?.["x-codex-parent-thread-id"]),
|
|
28
|
+
parentTurnId: readId("parent turn", flat?.parent_turn_id, nested?.parent_turn_id, compatibility?.parent_turn_id),
|
|
29
|
+
rootTurnId: readId("root turn", flat?.root_turn_id, nested?.root_turn_id, compatibility?.root_turn_id),
|
|
30
|
+
requestKind,
|
|
31
|
+
threadSource: reconcileMetadataStrings("thread source", nested?.thread_source, compatibility?.thread_source),
|
|
32
|
+
subagent: reconcileMetadataStrings("subagent", flat?.["x-openai-subagent"], headers?.["x-openai-subagent"]),
|
|
33
|
+
subagentKind: reconcileMetadataStrings("subagent kind", nested?.subagent_kind, compatibility?.subagent_kind),
|
|
34
|
+
guardianClassifierSourceThreadId: readId("Guardian classifier source thread", nested?.guardian_classifier_source_thread_id, compatibility?.guardian_classifier_source_thread_id),
|
|
35
|
+
autoReviewEnabled: reconcileMetadataBooleans("automatic review", nested?.auto_review_enabled, compatibility?.auto_review_enabled),
|
|
36
|
+
nodeReplAutoReviewRequired: reconcileMetadataBooleans("model-required review", nested?.node_repl_auto_review_required, compatibility?.node_repl_auto_review_required),
|
|
37
|
+
generation
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function readNativeMetadata(raw) {
|
|
41
|
+
if (raw === void 0) return;
|
|
42
|
+
const encoded = readStringValue(raw);
|
|
43
|
+
if (encoded === void 0 || Buffer.byteLength(encoded) > MAX_NATIVE_METADATA_BYTES) throw new Error("Codex inference request is missing bounded native metadata");
|
|
44
|
+
let value;
|
|
45
|
+
try {
|
|
46
|
+
value = JSON.parse(encoded);
|
|
47
|
+
} catch {
|
|
48
|
+
throw new Error("Codex inference request has invalid native metadata");
|
|
49
|
+
}
|
|
50
|
+
if (!isRecord(value)) throw new Error("Codex inference request has invalid native metadata");
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
function reconcileMetadataStrings(field, ...values) {
|
|
54
|
+
let result;
|
|
55
|
+
for (const value of values) {
|
|
56
|
+
if (value == null) continue;
|
|
57
|
+
const candidate = readStringValue(value);
|
|
58
|
+
if (candidate === void 0 || Buffer.byteLength(candidate) > MAX_METADATA_FIELD_BYTES) throw new Error(`Codex inference ${field} metadata is invalid or exceeds its limit`);
|
|
59
|
+
if (result !== void 0 && candidate !== result) throw new Error(`Codex inference ${field} metadata disagrees`);
|
|
60
|
+
result = candidate;
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
function readId(field, ...values) {
|
|
65
|
+
const value = reconcileMetadataStrings(field, ...values);
|
|
66
|
+
if (value !== void 0 && (!value || value.trim() !== value)) throw new Error(`Codex inference ${field} metadata has an invalid identity`);
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
function reconcileMetadataBooleans(field, ...values) {
|
|
70
|
+
let result;
|
|
71
|
+
for (const value of values) {
|
|
72
|
+
if (value == null) continue;
|
|
73
|
+
const candidate = asBoolean(value);
|
|
74
|
+
if (candidate === void 0) throw new Error(`Codex inference ${field} metadata is invalid`);
|
|
75
|
+
if (result !== void 0 && candidate !== result) throw new Error(`Codex inference ${field} metadata disagrees`);
|
|
76
|
+
result = candidate;
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
export { readCodexInferenceMetadata as n, CODEX_INFERENCE_GENERATION_KEY as t };
|