@opengeni/codex 3.3.1-canary.38922642121001 → 3.4.0

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/dist/index.js CHANGED
@@ -873,234 +873,609 @@ function opaqueProviderArtifactFingerprints(input) {
873
873
  });
874
874
  }
875
875
 
876
- // src/fetch.ts
877
- function emitRequestPreparationDiagnostic(ctx, phase) {
876
+ // src/responses-websocket.ts
877
+ var CODEX_RESPONSES_WEBSOCKET_BETA = "responses_websockets=2026-02-06";
878
+ var CODEX_TRANSPORT_HEADER = "x-opengeni-codex-transport";
879
+ var HTTP_REASONS = /* @__PURE__ */ new Set([
880
+ "not_eligible",
881
+ "connection_busy",
882
+ "handshake_backoff",
883
+ "handshake_failed",
884
+ "unavailable"
885
+ ]);
886
+ function formatCodexRequestTransport(transport) {
887
+ return transport.kind === "websocket" ? `websocket; connection=${transport.connection}` : `http; reason=${transport.reason}`;
888
+ }
889
+ function parseCodexRequestTransport(value) {
890
+ if (!value) return null;
891
+ const [kind, ...parameters] = value.split(";").map((part) => part.trim());
892
+ const fields = new Map(
893
+ parameters.map((parameter) => {
894
+ const index = parameter.indexOf("=");
895
+ return [parameter.slice(0, index), parameter.slice(index + 1)];
896
+ })
897
+ );
898
+ if (kind === "websocket") {
899
+ const connection = fields.get("connection");
900
+ return connection === "new" || connection === "reused" ? { kind: "websocket", connection } : null;
901
+ }
902
+ if (kind === "http") {
903
+ const reason = fields.get("reason");
904
+ return reason && HTTP_REASONS.has(reason) ? {
905
+ kind: "http",
906
+ reason
907
+ } : null;
908
+ }
909
+ return null;
910
+ }
911
+ function withTransport(response, transport) {
912
+ const value = formatCodexRequestTransport(transport);
878
913
  try {
879
- ctx.onRequestPreparationDiagnostic?.(phase);
914
+ response.headers.set(CODEX_TRANSPORT_HEADER, value);
915
+ return response;
880
916
  } catch {
917
+ const headers = new Headers(response.headers);
918
+ headers.set(CODEX_TRANSPORT_HEADER, value);
919
+ return new Response(response.body, {
920
+ status: response.status,
921
+ statusText: response.statusText,
922
+ headers
923
+ });
881
924
  }
882
925
  }
883
- var CODEX_TRANSPORT_ERROR_HEADER = "x-opengeni-codex-transport-error";
884
- var CODEX_REQUEST_BODY_NORMALIZED_HEADER = "x-opengeni-request-body-normalized";
885
- var REPLAYABLE_REQUEST_BODY_FACTORY = Symbol.for("opengeni.replayable-request-body-factory");
886
- var CODEX_REQUEST_MODEL_HEADER = "x-opengeni-request-model";
887
- var CODEX_REQUEST_ID_HEADER = "x-opengeni-request-id";
888
- var CODEX_REQUEST_CALLER_STREAM_HEADER = "x-opengeni-request-caller-stream";
889
- var MAX_CODEX_ERROR_BODY_BYTES = 64 * 1024;
890
- function headersCarryCodexTransportMarker(headers) {
891
- if (!headers || typeof headers !== "object") return false;
892
- const getter = headers.get;
893
- if (typeof getter === "function") {
894
- return getter.call(headers, CODEX_TRANSPORT_ERROR_HEADER) === "1";
895
- }
896
- const record = headers;
897
- return record[CODEX_TRANSPORT_ERROR_HEADER] === "1" || record[CODEX_TRANSPORT_ERROR_HEADER.toLowerCase()] === "1";
926
+ var DEFAULT_IDLE_MS = 5 * 6e4;
927
+ var DEFAULT_MAX_AGE_MS = 45 * 6e4;
928
+ var DEFAULT_CONNECT_TIMEOUT_MS = 1e4;
929
+ var DEFAULT_HANDSHAKE_BACKOFF_MS = 5 * 6e4;
930
+ var PER_REQUEST_HEADERS = /* @__PURE__ */ new Set([
931
+ "accept",
932
+ "content-type",
933
+ "content-length",
934
+ "idempotency-key",
935
+ "openai-beta"
936
+ ]);
937
+ var TERMINAL_EVENTS = /* @__PURE__ */ new Set([
938
+ "response.completed",
939
+ "response.done",
940
+ "response.failed",
941
+ "response.incomplete",
942
+ "response.error",
943
+ "error"
944
+ ]);
945
+ var RATE_LIMITS_EVENT = "codex.rate_limits";
946
+ var METADATA_EVENT = "codex.response.metadata";
947
+ var TIMING_EVENT = "responsesapi.websocket_timing";
948
+ var HEADER_NAME = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
949
+ function bunWebSocketFactory() {
950
+ const runtime = globalThis;
951
+ if (!runtime.Bun || typeof runtime.WebSocket !== "function") return null;
952
+ const Socket = runtime.WebSocket;
953
+ return (url, headers) => new Socket(url, { headers });
898
954
  }
899
- function isCodexTransportError(error) {
900
- let current = error;
901
- for (let depth = 0; depth < 6 && current && typeof current === "object"; depth += 1) {
902
- const value = current;
903
- if (headersCarryCodexTransportMarker(value.headers)) return true;
904
- current = value.cause;
905
- }
906
- return false;
955
+ function eventData(data) {
956
+ if (typeof data === "string") return data;
957
+ if (data instanceof ArrayBuffer) return new TextDecoder().decode(data);
958
+ if (ArrayBuffer.isView(data)) return new TextDecoder().decode(data);
959
+ return null;
907
960
  }
908
- var CODEX_ENCRYPTED_CONTENT_REJECTION_CODE = "invalid_encrypted_content";
909
- function classifyCodexEncryptedArtifactRejection(error) {
910
- if (!isCodexTransportError(error)) return null;
911
- let current = error;
912
- for (let depth = 0; depth < 6 && current && typeof current === "object"; depth += 1) {
913
- const value = current;
914
- const body = value.error && typeof value.error === "object" ? value.error : null;
915
- const status = Number(value.status ?? body?.status);
916
- const exactCode = typeof body?.code === "string" ? body.code : typeof value.code === "string" ? value.code : "";
917
- if (status === 400 && exactCode === CODEX_ENCRYPTED_CONTENT_REJECTION_CODE) {
918
- return { status: 400, kind: "encrypted_content_rejected" };
919
- }
920
- const message = [
921
- typeof value.message === "string" ? value.message : "",
922
- typeof body?.message === "string" ? body.message : "",
923
- typeof value.code === "string" ? value.code : "",
924
- typeof body?.code === "string" ? body.code : "",
925
- typeof value.type === "string" ? value.type : "",
926
- typeof body?.type === "string" ? body.type : ""
927
- ].join(" ").toLowerCase();
928
- const unsupportedFieldShape = /(?:invalid value|supported values?|unsupported|unknown (?:field|parameter|value))/.test(
929
- message
930
- );
931
- if (status === 400 && !unsupportedFieldShape && /(?:encrypted[_ ]content|encrypted reasoning|reasoning artifact)/.test(message) && /(?:decrypt(?:ed|ion)?|could not be parsed|cannot be parsed|failed to parse)/.test(message)) {
932
- return { status: 400, kind: "encrypted_content_rejected" };
961
+ function codexRateLimitHeaders(event) {
962
+ const limits = event.rate_limits;
963
+ if (!limits || typeof limits !== "object") return [];
964
+ const headers = [];
965
+ for (const slot of ["primary", "secondary"]) {
966
+ const window = limits[slot];
967
+ if (!window || typeof window !== "object") continue;
968
+ const value = window;
969
+ const number3 = (field) => typeof value[field] === "number" && Number.isFinite(value[field]) ? Math.round(value[field]) : null;
970
+ const used = number3("used_percent");
971
+ const minutes = number3("window_minutes");
972
+ const resetAfter = number3("reset_after_seconds");
973
+ const resetAt = number3("reset_at");
974
+ if (used !== null) headers.push([`x-codex-${slot}-used-percent`, String(used)]);
975
+ if (minutes !== null) {
976
+ headers.push([`x-codex-${slot}-window-minutes`, String(minutes)]);
977
+ headers.push([`x-codex-${slot}-limit-window-seconds`, String(minutes * 60)]);
933
978
  }
934
- current = value.cause;
979
+ if (resetAfter !== null)
980
+ headers.push([`x-codex-${slot}-reset-after-seconds`, String(resetAfter)]);
981
+ if (resetAt !== null) headers.push([`x-codex-${slot}-reset-at`, String(resetAt)]);
935
982
  }
936
- return null;
983
+ return headers;
937
984
  }
938
- function parseIntHeader(value) {
939
- if (value === null) {
940
- return null;
941
- }
942
- const n = Number.parseInt(value.trim(), 10);
943
- return Number.isFinite(n) ? n : null;
985
+ function metadataHeaders(event) {
986
+ const headers = event.headers;
987
+ if (!headers || typeof headers !== "object") return [];
988
+ return Object.entries(headers).flatMap(
989
+ ([name, value]) => HEADER_NAME.test(name) && typeof value === "string" && !/[\r\n]/.test(value) ? [[name.toLowerCase(), value]] : []
990
+ );
944
991
  }
945
- function resolveResetAt(headers, atKey, afterKey, nowMs) {
946
- const at = parseIntHeader(headers.get(atKey));
947
- if (at !== null) {
948
- return new Date(at * 1e3);
949
- }
950
- const after = parseIntHeader(headers.get(afterKey));
951
- if (after !== null) {
952
- return new Date(nowMs + after * 1e3);
953
- }
992
+ function sseBlock(event) {
993
+ const type = typeof event.type === "string" ? event.type : "message";
994
+ return new TextEncoder().encode(`event: ${type}
995
+ data: ${JSON.stringify(event)}
996
+
997
+ `);
998
+ }
999
+ function requestUrl(input) {
1000
+ if (typeof input === "string") return input;
1001
+ if (input instanceof URL) return input.toString();
954
1002
  return null;
955
1003
  }
956
- function parseCodexUsageHeaders(headers) {
957
- const duration = (slot) => {
958
- const raw = headers.get(`x-codex-${slot}-limit-window-seconds`);
959
- if (raw === null || !/^\d+$/.test(raw.trim())) return null;
960
- return Number(raw.trim());
1004
+ function codexResponsesTransport(http, options = {}) {
1005
+ const createSocket = options.createSocket === void 0 ? bunWebSocketFactory() : options.createSocket;
1006
+ if (!createSocket) return http;
1007
+ const idleMs = options.idleMs ?? DEFAULT_IDLE_MS;
1008
+ const maxAgeMs = options.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
1009
+ const connectTimeoutMs = options.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
1010
+ const handshakeBackoffMs = options.handshakeBackoffMs ?? DEFAULT_HANDSHAKE_BACKOFF_MS;
1011
+ const now = options.now ?? Date.now;
1012
+ const pool = /* @__PURE__ */ new Map();
1013
+ const backoffUntil = /* @__PURE__ */ new Map();
1014
+ const retire = (connection) => {
1015
+ if (connection.idleTimer) clearTimeout(connection.idleTimer);
1016
+ connection.idleTimer = null;
1017
+ if (pool.get(connection.key) === connection) pool.delete(connection.key);
1018
+ if (!connection.closed) {
1019
+ connection.closed = true;
1020
+ try {
1021
+ connection.socket.close(1e3, "done");
1022
+ } catch {
1023
+ }
1024
+ }
961
1025
  };
962
- const primarySeconds = duration("primary");
963
- const secondarySeconds = duration("secondary");
964
- if (!(primarySeconds === CODEX_FIVE_HOUR_WINDOW_SECONDS && secondarySeconds === CODEX_WEEKLY_WINDOW_SECONDS || primarySeconds === CODEX_WEEKLY_WINDOW_SECONDS && secondarySeconds === CODEX_FIVE_HOUR_WINDOW_SECONDS)) {
965
- return null;
966
- }
967
- const first = parseIntHeader(headers.get("x-codex-primary-used-percent"));
968
- const second = parseIntHeader(headers.get("x-codex-secondary-used-percent"));
969
- if (first === null || second === null) return null;
970
- const nowMs = Date.now();
971
- const primaryResetAt = resolveResetAt(
972
- headers,
973
- "x-codex-primary-reset-at",
974
- "x-codex-primary-reset-after-seconds",
975
- nowMs
976
- );
977
- const secondaryResetAt = resolveResetAt(
978
- headers,
979
- "x-codex-secondary-reset-at",
980
- "x-codex-secondary-reset-after-seconds",
981
- nowMs
982
- );
983
- const firstIsFiveHour = primarySeconds === CODEX_FIVE_HOUR_WINDOW_SECONDS;
984
- return {
985
- primaryUsedPercent: firstIsFiveHour ? first : second,
986
- primaryResetAt: firstIsFiveHour ? primaryResetAt : secondaryResetAt,
987
- secondaryUsedPercent: firstIsFiveHour ? second : first,
988
- secondaryResetAt: firstIsFiveHour ? secondaryResetAt : primaryResetAt,
989
- checkedAt: new Date(nowMs)
1026
+ const release = (connection) => {
1027
+ connection.busy = false;
1028
+ connection.onEvent = null;
1029
+ connection.onClose = null;
1030
+ if (connection.closed) return;
1031
+ if (connection.idleTimer) clearTimeout(connection.idleTimer);
1032
+ connection.idleTimer = setTimeout(() => retire(connection), idleMs);
1033
+ connection.idleTimer.unref?.();
990
1034
  };
991
- }
992
- function settleProviderRequest(audit, outcome) {
993
- if (!audit.admitted) return Promise.resolve();
994
- if (!audit.settlement) {
995
- audit.settlement = (async () => {
996
- await audit.ctx.onProviderRequestSettled?.({
997
- requestId: audit.requestId,
998
- transportAttempt: audit.transportAttempt,
999
- outcome
1000
- });
1001
- })();
1002
- void audit.settlement.catch(() => void 0);
1003
- }
1004
- return audit.settlement;
1005
- }
1006
- function classifyCodexSseTerminal(ev) {
1007
- if (ev.type === "response.failed") {
1008
- return {
1009
- phase: "failed",
1010
- rawError: ev.response?.error,
1011
- fallbackCode: "response_failed",
1012
- fallbackMessage: "The Codex response failed"
1035
+ const connect = (url, key, headers) => new Promise((resolve, reject) => {
1036
+ let socket;
1037
+ try {
1038
+ socket = createSocket(url, headers);
1039
+ } catch (error) {
1040
+ reject(error);
1041
+ return;
1042
+ }
1043
+ const connection = {
1044
+ key,
1045
+ socket,
1046
+ openedAt: now(),
1047
+ busy: false,
1048
+ closed: false,
1049
+ requests: 0,
1050
+ idleTimer: null,
1051
+ onEvent: null,
1052
+ onClose: null
1013
1053
  };
1014
- }
1015
- if (ev.type === "error" || ev.type === "response.error") {
1016
- return {
1017
- phase: "failed",
1018
- rawError: ev.error ?? ev.response?.error ?? ev,
1019
- fallbackCode: "response_error",
1020
- fallbackMessage: "The Codex response stream reported an error"
1054
+ let opened = false;
1055
+ const timer = setTimeout(() => {
1056
+ if (opened) return;
1057
+ connection.closed = true;
1058
+ try {
1059
+ socket.close();
1060
+ } catch {
1061
+ }
1062
+ reject(new Error("Codex response WebSocket handshake timed out"));
1063
+ }, connectTimeoutMs);
1064
+ socket.onopen = () => {
1065
+ opened = true;
1066
+ clearTimeout(timer);
1067
+ resolve(connection);
1021
1068
  };
1022
- }
1023
- if (ev.type === "response.incomplete") {
1024
- const details = ev.response?.incomplete_details;
1025
- const reason = details && typeof details === "object" ? details.reason : void 0;
1026
- return {
1027
- phase: "failed",
1028
- rawError: {
1029
- code: "response_incomplete",
1030
- message: typeof reason === "string" && reason.length > 0 ? `The Codex response was incomplete (${reason})` : "The Codex response was incomplete"
1031
- },
1032
- fallbackCode: "response_incomplete",
1033
- fallbackMessage: "The Codex response was incomplete"
1069
+ socket.onerror = () => {
1034
1070
  };
1035
- }
1036
- if (ev.type !== "response.completed" && ev.type !== "response.done") {
1037
- return null;
1038
- }
1039
- if (!ev.response) {
1040
- return null;
1041
- }
1042
- const responseStatus = ev.response.status;
1043
- if (responseStatus !== void 0 && responseStatus !== "completed" || ev.response.error !== null && ev.response.error !== void 0) {
1044
- const incomplete = responseStatus === "incomplete";
1045
- return {
1046
- phase: "failed",
1047
- rawError: ev.response.error,
1048
- fallbackCode: incomplete ? "response_incomplete" : "response_failed",
1049
- fallbackMessage: incomplete ? "The Codex response was incomplete" : "The Codex response failed"
1071
+ socket.onclose = (event) => {
1072
+ clearTimeout(timer);
1073
+ connection.closed = true;
1074
+ if (pool.get(key) === connection) pool.delete(key);
1075
+ if (connection.idleTimer) clearTimeout(connection.idleTimer);
1076
+ if (!opened) {
1077
+ reject(
1078
+ new Error(`Codex response WebSocket handshake failed (${event?.code ?? "closed"})`)
1079
+ );
1080
+ return;
1081
+ }
1082
+ connection.onClose?.(
1083
+ new Error(
1084
+ `Codex response WebSocket closed before the response finished (${event?.code ?? "closed"})`
1085
+ )
1086
+ );
1050
1087
  };
1051
- }
1052
- return { phase: "completed" };
1053
- }
1054
- function markSemanticTerminal(state, phase) {
1055
- if (state.phase === null) {
1056
- state.phase = phase;
1057
- }
1058
- }
1059
- function semanticCompletionEvidence(state) {
1060
- return state?.phase === "completed" ? { meaningfulOutput: state.meaningfulOutput === true } : {};
1061
- }
1062
- function terminalOutcomeForPhase(phase) {
1063
- if (phase === "completed" || phase === "failed" || phase === "timed_out") {
1064
- return phase;
1065
- }
1066
- return null;
1067
- }
1068
- function requestEventFor(audit, event) {
1069
- return {
1070
- requestId: audit.requestId,
1071
- transportAttempt: audit.transportAttempt,
1072
- ...audit.model ? { model: audit.model } : {},
1073
- durationMs: Math.max(0, performance.now() - audit.attemptStartedAtMonotonic),
1074
- timeoutPolicy: audit.policy,
1075
- ...event
1088
+ socket.onmessage = (message) => {
1089
+ const text = eventData(message.data);
1090
+ if (text === null) return;
1091
+ let parsed;
1092
+ try {
1093
+ parsed = JSON.parse(text);
1094
+ } catch {
1095
+ return;
1096
+ }
1097
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
1098
+ connection.onEvent?.(parsed);
1099
+ }
1100
+ };
1101
+ });
1102
+ return async (input, init) => {
1103
+ const url = requestUrl(input);
1104
+ const method = (init?.method ?? "GET").toUpperCase();
1105
+ const body = init?.body;
1106
+ if (!url || method !== "POST" || !/^https:\/\/[^/]+\/.*\/codex\/responses(?:\?|$)/.test(url)) {
1107
+ return await http(input, init);
1108
+ }
1109
+ const viaHttp = async (reason) => withTransport(await http(input, init), { kind: "http", reason });
1110
+ if (typeof body !== "string") return await viaHttp("not_eligible");
1111
+ let payload;
1112
+ try {
1113
+ const parsed = JSON.parse(body);
1114
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error();
1115
+ payload = parsed;
1116
+ } catch {
1117
+ return await viaHttp("not_eligible");
1118
+ }
1119
+ if (payload.stream !== true) return await viaHttp("not_eligible");
1120
+ const handshake = {};
1121
+ for (const [name, value] of new Headers(init?.headers).entries()) {
1122
+ if (!PER_REQUEST_HEADERS.has(name)) handshake[name] = value;
1123
+ }
1124
+ handshake["openai-beta"] = CODEX_RESPONSES_WEBSOCKET_BETA;
1125
+ const wsUrl = url.replace(/^https:/, "wss:");
1126
+ const key = JSON.stringify([wsUrl, Object.entries(handshake).sort()]);
1127
+ if ((backoffUntil.get(key) ?? 0) > now()) return await viaHttp("handshake_backoff");
1128
+ const signal = init?.signal ?? null;
1129
+ signal?.throwIfAborted();
1130
+ let connection = pool.get(key);
1131
+ if (connection && (connection.closed || now() - connection.openedAt > maxAgeMs)) {
1132
+ if (!connection.busy) retire(connection);
1133
+ connection = void 0;
1134
+ }
1135
+ if (connection?.busy) return await viaHttp("connection_busy");
1136
+ if (!connection) {
1137
+ try {
1138
+ connection = await connect(wsUrl, key, handshake);
1139
+ } catch {
1140
+ backoffUntil.set(key, now() + handshakeBackoffMs);
1141
+ return await viaHttp("handshake_failed");
1142
+ }
1143
+ if (pool.has(key)) {
1144
+ const existing = pool.get(key);
1145
+ if (!existing.busy && !existing.closed) {
1146
+ retire(connection);
1147
+ connection = existing;
1148
+ } else {
1149
+ pool.set(key, connection);
1150
+ }
1151
+ } else {
1152
+ pool.set(key, connection);
1153
+ }
1154
+ if (connection.busy) return await viaHttp("connection_busy");
1155
+ }
1156
+ const active = connection;
1157
+ const transport = {
1158
+ kind: "websocket",
1159
+ connection: active.requests === 0 ? "new" : "reused"
1160
+ };
1161
+ active.requests += 1;
1162
+ active.busy = true;
1163
+ if (active.idleTimer) clearTimeout(active.idleTimer);
1164
+ active.idleTimer = null;
1165
+ return await new Promise((resolve, reject) => {
1166
+ const headers = new Headers({
1167
+ "content-type": "text/event-stream",
1168
+ [CODEX_TRANSPORT_HEADER]: formatCodexRequestTransport(transport)
1169
+ });
1170
+ let controller = null;
1171
+ let started = false;
1172
+ let finished = false;
1173
+ const pending = [];
1174
+ const finish = (error) => {
1175
+ if (finished) return;
1176
+ finished = true;
1177
+ signal?.removeEventListener("abort", onAbort);
1178
+ if (error !== void 0) {
1179
+ retire(active);
1180
+ active.busy = false;
1181
+ if (started) controller?.error(error);
1182
+ else reject(error);
1183
+ return;
1184
+ }
1185
+ release(active);
1186
+ try {
1187
+ controller?.close();
1188
+ } catch {
1189
+ }
1190
+ };
1191
+ const onAbort = () => finish(signal?.reason ?? new Error("Model request aborted"));
1192
+ signal?.addEventListener("abort", onAbort, { once: true });
1193
+ const stream = new ReadableStream({
1194
+ start(streamController) {
1195
+ controller = streamController;
1196
+ for (const block of pending.splice(0)) streamController.enqueue(block);
1197
+ if (finished) streamController.close();
1198
+ },
1199
+ cancel() {
1200
+ if (!finished) finish(new Error("Model response stream cancelled"));
1201
+ }
1202
+ });
1203
+ const begin = (status = 200, errorBody) => {
1204
+ started = true;
1205
+ if (errorBody !== void 0) {
1206
+ headers.set("content-type", "application/json");
1207
+ resolve(new Response(errorBody, { status, headers }));
1208
+ return;
1209
+ }
1210
+ resolve(new Response(stream, { status, headers }));
1211
+ };
1212
+ active.onClose = (error) => finish(error);
1213
+ active.onEvent = (event) => {
1214
+ if (finished) return;
1215
+ const type = typeof event.type === "string" ? event.type : "";
1216
+ if (type === RATE_LIMITS_EVENT) {
1217
+ if (!started)
1218
+ for (const [name, value] of codexRateLimitHeaders(event)) headers.set(name, value);
1219
+ return;
1220
+ }
1221
+ if (type === METADATA_EVENT) {
1222
+ if (!started)
1223
+ for (const [name, value] of metadataHeaders(event)) headers.set(name, value);
1224
+ return;
1225
+ }
1226
+ if (type === TIMING_EVENT) return;
1227
+ if (!started && type === "error" && typeof event.status === "number") {
1228
+ for (const [name, value] of metadataHeaders(event)) headers.set(name, value);
1229
+ const status = event.status >= 400 && event.status < 600 ? event.status : 500;
1230
+ begin(status, JSON.stringify({ error: event.error ?? null }));
1231
+ finished = true;
1232
+ signal?.removeEventListener("abort", onAbort);
1233
+ release(active);
1234
+ return;
1235
+ }
1236
+ if (!started) begin();
1237
+ const block = sseBlock(event);
1238
+ if (controller) controller.enqueue(block);
1239
+ else pending.push(block);
1240
+ if (TERMINAL_EVENTS.has(type)) finish();
1241
+ };
1242
+ try {
1243
+ active.socket.send(JSON.stringify({ ...payload, type: "response.create" }));
1244
+ } catch (error) {
1245
+ finish(error);
1246
+ }
1247
+ });
1076
1248
  };
1077
1249
  }
1078
- async function emitRequestEvent(audit, event) {
1079
- const terminalOutcome = terminalOutcomeForPhase(event.phase);
1080
- if (terminalOutcome !== null) {
1081
- if (audit.terminalOutcome !== null) {
1082
- await audit.settlement;
1083
- return false;
1084
- }
1085
- audit.terminalOutcome = terminalOutcome;
1086
- await settleProviderRequest(
1087
- audit,
1088
- definiteErrorStatus(event.status) ? "refused" : event.phase === "completed" ? "response_received" : "unknown"
1089
- );
1090
- }
1091
- const observed = requestEventFor(audit, event);
1250
+
1251
+ // src/fetch.ts
1252
+ function emitRequestPreparationDiagnostic(ctx, phase) {
1092
1253
  try {
1093
- audit.ctx.onModelRequestDiagnostic?.(observed);
1254
+ ctx.onRequestPreparationDiagnostic?.(phase);
1094
1255
  } catch {
1095
1256
  }
1096
- await audit.ctx.onModelRequestEvent?.(observed);
1097
- return true;
1098
- }
1099
- function definiteErrorStatus(status) {
1100
- return status !== void 0 && status >= 400 && status < 600 && status !== 408 && status !== 409 && status !== 504;
1101
- }
1102
- function providerRequestId(headers) {
1103
- return headers.get("x-request-id") ?? headers.get("request-id") ?? void 0;
1257
+ }
1258
+ var CODEX_TRANSPORT_ERROR_HEADER = "x-opengeni-codex-transport-error";
1259
+ var CODEX_REQUEST_BODY_NORMALIZED_HEADER = "x-opengeni-request-body-normalized";
1260
+ var REPLAYABLE_REQUEST_BODY_FACTORY = Symbol.for("opengeni.replayable-request-body-factory");
1261
+ var CODEX_REQUEST_MODEL_HEADER = "x-opengeni-request-model";
1262
+ var CODEX_REQUEST_ID_HEADER = "x-opengeni-request-id";
1263
+ var CODEX_REQUEST_CALLER_STREAM_HEADER = "x-opengeni-request-caller-stream";
1264
+ var MAX_CODEX_ERROR_BODY_BYTES = 64 * 1024;
1265
+ function headersCarryCodexTransportMarker(headers) {
1266
+ if (!headers || typeof headers !== "object") return false;
1267
+ const getter = headers.get;
1268
+ if (typeof getter === "function") {
1269
+ return getter.call(headers, CODEX_TRANSPORT_ERROR_HEADER) === "1";
1270
+ }
1271
+ const record = headers;
1272
+ return record[CODEX_TRANSPORT_ERROR_HEADER] === "1" || record[CODEX_TRANSPORT_ERROR_HEADER.toLowerCase()] === "1";
1273
+ }
1274
+ function isCodexTransportError(error) {
1275
+ let current = error;
1276
+ for (let depth = 0; depth < 6 && current && typeof current === "object"; depth += 1) {
1277
+ const value = current;
1278
+ if (headersCarryCodexTransportMarker(value.headers)) return true;
1279
+ current = value.cause;
1280
+ }
1281
+ return false;
1282
+ }
1283
+ var CODEX_ENCRYPTED_CONTENT_REJECTION_CODE = "invalid_encrypted_content";
1284
+ function classifyCodexEncryptedArtifactRejection(error) {
1285
+ if (!isCodexTransportError(error)) return null;
1286
+ let current = error;
1287
+ for (let depth = 0; depth < 6 && current && typeof current === "object"; depth += 1) {
1288
+ const value = current;
1289
+ const body = value.error && typeof value.error === "object" ? value.error : null;
1290
+ const status = Number(value.status ?? body?.status);
1291
+ const exactCode = typeof body?.code === "string" ? body.code : typeof value.code === "string" ? value.code : "";
1292
+ if (status === 400 && exactCode === CODEX_ENCRYPTED_CONTENT_REJECTION_CODE) {
1293
+ return { status: 400, kind: "encrypted_content_rejected" };
1294
+ }
1295
+ const message = [
1296
+ typeof value.message === "string" ? value.message : "",
1297
+ typeof body?.message === "string" ? body.message : "",
1298
+ typeof value.code === "string" ? value.code : "",
1299
+ typeof body?.code === "string" ? body.code : "",
1300
+ typeof value.type === "string" ? value.type : "",
1301
+ typeof body?.type === "string" ? body.type : ""
1302
+ ].join(" ").toLowerCase();
1303
+ const unsupportedFieldShape = /(?:invalid value|supported values?|unsupported|unknown (?:field|parameter|value))/.test(
1304
+ message
1305
+ );
1306
+ if (status === 400 && !unsupportedFieldShape && /(?:encrypted[_ ]content|encrypted reasoning|reasoning artifact)/.test(message) && /(?:decrypt(?:ed|ion)?|could not be parsed|cannot be parsed|failed to parse)/.test(message)) {
1307
+ return { status: 400, kind: "encrypted_content_rejected" };
1308
+ }
1309
+ current = value.cause;
1310
+ }
1311
+ return null;
1312
+ }
1313
+ function parseIntHeader(value) {
1314
+ if (value === null) {
1315
+ return null;
1316
+ }
1317
+ const n = Number.parseInt(value.trim(), 10);
1318
+ return Number.isFinite(n) ? n : null;
1319
+ }
1320
+ function resolveResetAt(headers, atKey, afterKey, nowMs) {
1321
+ const at = parseIntHeader(headers.get(atKey));
1322
+ if (at !== null) {
1323
+ return new Date(at * 1e3);
1324
+ }
1325
+ const after = parseIntHeader(headers.get(afterKey));
1326
+ if (after !== null) {
1327
+ return new Date(nowMs + after * 1e3);
1328
+ }
1329
+ return null;
1330
+ }
1331
+ function parseCodexUsageHeaders(headers) {
1332
+ const duration = (slot) => {
1333
+ const raw = headers.get(`x-codex-${slot}-limit-window-seconds`);
1334
+ if (raw === null || !/^\d+$/.test(raw.trim())) return null;
1335
+ return Number(raw.trim());
1336
+ };
1337
+ const primarySeconds = duration("primary");
1338
+ const secondarySeconds = duration("secondary");
1339
+ if (!(primarySeconds === CODEX_FIVE_HOUR_WINDOW_SECONDS && secondarySeconds === CODEX_WEEKLY_WINDOW_SECONDS || primarySeconds === CODEX_WEEKLY_WINDOW_SECONDS && secondarySeconds === CODEX_FIVE_HOUR_WINDOW_SECONDS)) {
1340
+ return null;
1341
+ }
1342
+ const first = parseIntHeader(headers.get("x-codex-primary-used-percent"));
1343
+ const second = parseIntHeader(headers.get("x-codex-secondary-used-percent"));
1344
+ if (first === null || second === null) return null;
1345
+ const nowMs = Date.now();
1346
+ const primaryResetAt = resolveResetAt(
1347
+ headers,
1348
+ "x-codex-primary-reset-at",
1349
+ "x-codex-primary-reset-after-seconds",
1350
+ nowMs
1351
+ );
1352
+ const secondaryResetAt = resolveResetAt(
1353
+ headers,
1354
+ "x-codex-secondary-reset-at",
1355
+ "x-codex-secondary-reset-after-seconds",
1356
+ nowMs
1357
+ );
1358
+ const firstIsFiveHour = primarySeconds === CODEX_FIVE_HOUR_WINDOW_SECONDS;
1359
+ return {
1360
+ primaryUsedPercent: firstIsFiveHour ? first : second,
1361
+ primaryResetAt: firstIsFiveHour ? primaryResetAt : secondaryResetAt,
1362
+ secondaryUsedPercent: firstIsFiveHour ? second : first,
1363
+ secondaryResetAt: firstIsFiveHour ? secondaryResetAt : primaryResetAt,
1364
+ checkedAt: new Date(nowMs)
1365
+ };
1366
+ }
1367
+ function settleProviderRequest(audit, outcome) {
1368
+ if (!audit.admitted) return Promise.resolve();
1369
+ if (!audit.settlement) {
1370
+ audit.settlement = (async () => {
1371
+ await audit.ctx.onProviderRequestSettled?.({
1372
+ requestId: audit.requestId,
1373
+ transportAttempt: audit.transportAttempt,
1374
+ outcome
1375
+ });
1376
+ })();
1377
+ void audit.settlement.catch(() => void 0);
1378
+ }
1379
+ return audit.settlement;
1380
+ }
1381
+ function classifyCodexSseTerminal(ev) {
1382
+ if (ev.type === "response.failed") {
1383
+ return {
1384
+ phase: "failed",
1385
+ rawError: ev.response?.error,
1386
+ fallbackCode: "response_failed",
1387
+ fallbackMessage: "The Codex response failed"
1388
+ };
1389
+ }
1390
+ if (ev.type === "error" || ev.type === "response.error") {
1391
+ return {
1392
+ phase: "failed",
1393
+ rawError: ev.error ?? ev.response?.error ?? ev,
1394
+ fallbackCode: "response_error",
1395
+ fallbackMessage: "The Codex response stream reported an error"
1396
+ };
1397
+ }
1398
+ if (ev.type === "response.incomplete") {
1399
+ const details = ev.response?.incomplete_details;
1400
+ const reason = details && typeof details === "object" ? details.reason : void 0;
1401
+ return {
1402
+ phase: "failed",
1403
+ rawError: {
1404
+ code: "response_incomplete",
1405
+ message: typeof reason === "string" && reason.length > 0 ? `The Codex response was incomplete (${reason})` : "The Codex response was incomplete"
1406
+ },
1407
+ fallbackCode: "response_incomplete",
1408
+ fallbackMessage: "The Codex response was incomplete"
1409
+ };
1410
+ }
1411
+ if (ev.type !== "response.completed" && ev.type !== "response.done") {
1412
+ return null;
1413
+ }
1414
+ if (!ev.response) {
1415
+ return null;
1416
+ }
1417
+ const responseStatus = ev.response.status;
1418
+ if (responseStatus !== void 0 && responseStatus !== "completed" || ev.response.error !== null && ev.response.error !== void 0) {
1419
+ const incomplete = responseStatus === "incomplete";
1420
+ return {
1421
+ phase: "failed",
1422
+ rawError: ev.response.error,
1423
+ fallbackCode: incomplete ? "response_incomplete" : "response_failed",
1424
+ fallbackMessage: incomplete ? "The Codex response was incomplete" : "The Codex response failed"
1425
+ };
1426
+ }
1427
+ return { phase: "completed" };
1428
+ }
1429
+ function markSemanticTerminal(state, phase) {
1430
+ if (state.phase === null) {
1431
+ state.phase = phase;
1432
+ }
1433
+ }
1434
+ function semanticCompletionEvidence(state) {
1435
+ return state?.phase === "completed" ? { meaningfulOutput: state.meaningfulOutput === true } : {};
1436
+ }
1437
+ function terminalOutcomeForPhase(phase) {
1438
+ if (phase === "completed" || phase === "failed" || phase === "timed_out") {
1439
+ return phase;
1440
+ }
1441
+ return null;
1442
+ }
1443
+ function requestEventFor(audit, event) {
1444
+ return {
1445
+ requestId: audit.requestId,
1446
+ transportAttempt: audit.transportAttempt,
1447
+ ...audit.model ? { model: audit.model } : {},
1448
+ durationMs: Math.max(0, performance.now() - audit.attemptStartedAtMonotonic),
1449
+ timeoutPolicy: audit.policy,
1450
+ ...event
1451
+ };
1452
+ }
1453
+ async function emitRequestEvent(audit, event) {
1454
+ const terminalOutcome = terminalOutcomeForPhase(event.phase);
1455
+ if (terminalOutcome !== null) {
1456
+ if (audit.terminalOutcome !== null) {
1457
+ await audit.settlement;
1458
+ return false;
1459
+ }
1460
+ audit.terminalOutcome = terminalOutcome;
1461
+ await settleProviderRequest(
1462
+ audit,
1463
+ definiteErrorStatus(event.status) ? "refused" : event.phase === "completed" ? "response_received" : "unknown"
1464
+ );
1465
+ }
1466
+ const observed = requestEventFor(audit, event);
1467
+ try {
1468
+ audit.ctx.onModelRequestDiagnostic?.(observed);
1469
+ } catch {
1470
+ }
1471
+ await audit.ctx.onModelRequestEvent?.(observed);
1472
+ return true;
1473
+ }
1474
+ function definiteErrorStatus(status) {
1475
+ return status !== void 0 && status >= 400 && status < 600 && status !== 408 && status !== 409 && status !== 504;
1476
+ }
1477
+ function providerRequestId(headers) {
1478
+ return headers.get("x-request-id") ?? headers.get("request-id") ?? void 0;
1104
1479
  }
1105
1480
  async function fetchBeforeHeaders(base, input, init, audit) {
1106
1481
  const elapsed = Date.now() - audit.logicalStartedAt;
@@ -1460,7 +1835,12 @@ function codexSubscriptionFetch(base = globalThis.fetch) {
1460
1835
  phase: "headers",
1461
1836
  responseObserved: true,
1462
1837
  status: res.status,
1463
- ...upstreamRequestId ? { providerRequestId: upstreamRequestId } : {}
1838
+ ...upstreamRequestId ? { providerRequestId: upstreamRequestId } : {},
1839
+ // A response the socket transport did not label never passed through it.
1840
+ transport: parseCodexRequestTransport(res.headers.get(CODEX_TRANSPORT_HEADER)) ?? {
1841
+ kind: "http",
1842
+ reason: "unavailable"
1843
+ }
1464
1844
  });
1465
1845
  res = await observedResponse(res, audit, nextInit.signal, semanticTerminal);
1466
1846
  } catch (error) {
@@ -2037,322 +2417,6 @@ function inspectCodexSseBlock(block, source, onSemanticTerminal, onOutput) {
2037
2417
  return false;
2038
2418
  }
2039
2419
 
2040
- // src/responses-websocket.ts
2041
- var CODEX_RESPONSES_WEBSOCKET_BETA = "responses_websockets=2026-02-06";
2042
- var DEFAULT_IDLE_MS = 5 * 6e4;
2043
- var DEFAULT_MAX_AGE_MS = 45 * 6e4;
2044
- var DEFAULT_CONNECT_TIMEOUT_MS = 1e4;
2045
- var DEFAULT_HANDSHAKE_BACKOFF_MS = 5 * 6e4;
2046
- var PER_REQUEST_HEADERS = /* @__PURE__ */ new Set([
2047
- "accept",
2048
- "content-type",
2049
- "content-length",
2050
- "idempotency-key",
2051
- "openai-beta"
2052
- ]);
2053
- var TERMINAL_EVENTS = /* @__PURE__ */ new Set([
2054
- "response.completed",
2055
- "response.done",
2056
- "response.failed",
2057
- "response.incomplete",
2058
- "response.error",
2059
- "error"
2060
- ]);
2061
- var RATE_LIMITS_EVENT = "codex.rate_limits";
2062
- var METADATA_EVENT = "codex.response.metadata";
2063
- var TIMING_EVENT = "responsesapi.websocket_timing";
2064
- var HEADER_NAME = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
2065
- function bunWebSocketFactory() {
2066
- const runtime = globalThis;
2067
- if (!runtime.Bun || typeof runtime.WebSocket !== "function") return null;
2068
- const Socket = runtime.WebSocket;
2069
- return (url, headers) => new Socket(url, { headers });
2070
- }
2071
- function eventData(data) {
2072
- if (typeof data === "string") return data;
2073
- if (data instanceof ArrayBuffer) return new TextDecoder().decode(data);
2074
- if (ArrayBuffer.isView(data)) return new TextDecoder().decode(data);
2075
- return null;
2076
- }
2077
- function codexRateLimitHeaders(event) {
2078
- const limits = event.rate_limits;
2079
- if (!limits || typeof limits !== "object") return [];
2080
- const headers = [];
2081
- for (const slot of ["primary", "secondary"]) {
2082
- const window = limits[slot];
2083
- if (!window || typeof window !== "object") continue;
2084
- const value = window;
2085
- const number3 = (field) => typeof value[field] === "number" && Number.isFinite(value[field]) ? Math.round(value[field]) : null;
2086
- const used = number3("used_percent");
2087
- const minutes = number3("window_minutes");
2088
- const resetAfter = number3("reset_after_seconds");
2089
- const resetAt = number3("reset_at");
2090
- if (used !== null) headers.push([`x-codex-${slot}-used-percent`, String(used)]);
2091
- if (minutes !== null) {
2092
- headers.push([`x-codex-${slot}-window-minutes`, String(minutes)]);
2093
- headers.push([`x-codex-${slot}-limit-window-seconds`, String(minutes * 60)]);
2094
- }
2095
- if (resetAfter !== null)
2096
- headers.push([`x-codex-${slot}-reset-after-seconds`, String(resetAfter)]);
2097
- if (resetAt !== null) headers.push([`x-codex-${slot}-reset-at`, String(resetAt)]);
2098
- }
2099
- return headers;
2100
- }
2101
- function metadataHeaders(event) {
2102
- const headers = event.headers;
2103
- if (!headers || typeof headers !== "object") return [];
2104
- return Object.entries(headers).flatMap(
2105
- ([name, value]) => HEADER_NAME.test(name) && typeof value === "string" && !/[\r\n]/.test(value) ? [[name.toLowerCase(), value]] : []
2106
- );
2107
- }
2108
- function sseBlock(event) {
2109
- const type = typeof event.type === "string" ? event.type : "message";
2110
- return new TextEncoder().encode(`event: ${type}
2111
- data: ${JSON.stringify(event)}
2112
-
2113
- `);
2114
- }
2115
- function requestUrl(input) {
2116
- if (typeof input === "string") return input;
2117
- if (input instanceof URL) return input.toString();
2118
- return null;
2119
- }
2120
- function codexResponsesTransport(http, options = {}) {
2121
- const createSocket = options.createSocket === void 0 ? bunWebSocketFactory() : options.createSocket;
2122
- if (!createSocket) return http;
2123
- const idleMs = options.idleMs ?? DEFAULT_IDLE_MS;
2124
- const maxAgeMs = options.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
2125
- const connectTimeoutMs = options.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
2126
- const handshakeBackoffMs = options.handshakeBackoffMs ?? DEFAULT_HANDSHAKE_BACKOFF_MS;
2127
- const now = options.now ?? Date.now;
2128
- const pool = /* @__PURE__ */ new Map();
2129
- const backoffUntil = /* @__PURE__ */ new Map();
2130
- const retire = (connection) => {
2131
- if (connection.idleTimer) clearTimeout(connection.idleTimer);
2132
- connection.idleTimer = null;
2133
- if (pool.get(connection.key) === connection) pool.delete(connection.key);
2134
- if (!connection.closed) {
2135
- connection.closed = true;
2136
- try {
2137
- connection.socket.close(1e3, "done");
2138
- } catch {
2139
- }
2140
- }
2141
- };
2142
- const release = (connection) => {
2143
- connection.busy = false;
2144
- connection.onEvent = null;
2145
- connection.onClose = null;
2146
- if (connection.closed) return;
2147
- if (connection.idleTimer) clearTimeout(connection.idleTimer);
2148
- connection.idleTimer = setTimeout(() => retire(connection), idleMs);
2149
- connection.idleTimer.unref?.();
2150
- };
2151
- const connect = (url, key, headers) => new Promise((resolve, reject) => {
2152
- let socket;
2153
- try {
2154
- socket = createSocket(url, headers);
2155
- } catch (error) {
2156
- reject(error);
2157
- return;
2158
- }
2159
- const connection = {
2160
- key,
2161
- socket,
2162
- openedAt: now(),
2163
- busy: false,
2164
- closed: false,
2165
- idleTimer: null,
2166
- onEvent: null,
2167
- onClose: null
2168
- };
2169
- let opened = false;
2170
- const timer = setTimeout(() => {
2171
- if (opened) return;
2172
- connection.closed = true;
2173
- try {
2174
- socket.close();
2175
- } catch {
2176
- }
2177
- reject(new Error("Codex response WebSocket handshake timed out"));
2178
- }, connectTimeoutMs);
2179
- socket.onopen = () => {
2180
- opened = true;
2181
- clearTimeout(timer);
2182
- resolve(connection);
2183
- };
2184
- socket.onerror = () => {
2185
- };
2186
- socket.onclose = (event) => {
2187
- clearTimeout(timer);
2188
- connection.closed = true;
2189
- if (pool.get(key) === connection) pool.delete(key);
2190
- if (connection.idleTimer) clearTimeout(connection.idleTimer);
2191
- if (!opened) {
2192
- reject(
2193
- new Error(`Codex response WebSocket handshake failed (${event?.code ?? "closed"})`)
2194
- );
2195
- return;
2196
- }
2197
- connection.onClose?.(
2198
- new Error(
2199
- `Codex response WebSocket closed before the response finished (${event?.code ?? "closed"})`
2200
- )
2201
- );
2202
- };
2203
- socket.onmessage = (message) => {
2204
- const text = eventData(message.data);
2205
- if (text === null) return;
2206
- let parsed;
2207
- try {
2208
- parsed = JSON.parse(text);
2209
- } catch {
2210
- return;
2211
- }
2212
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
2213
- connection.onEvent?.(parsed);
2214
- }
2215
- };
2216
- });
2217
- return async (input, init) => {
2218
- const url = requestUrl(input);
2219
- const method = (init?.method ?? "GET").toUpperCase();
2220
- const body = init?.body;
2221
- if (!url || method !== "POST" || typeof body !== "string" || !/^https:\/\/[^/]+\/.*\/codex\/responses(?:\?|$)/.test(url)) {
2222
- return await http(input, init);
2223
- }
2224
- let payload;
2225
- try {
2226
- const parsed = JSON.parse(body);
2227
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error();
2228
- payload = parsed;
2229
- } catch {
2230
- return await http(input, init);
2231
- }
2232
- if (payload.stream !== true) return await http(input, init);
2233
- const handshake = {};
2234
- for (const [name, value] of new Headers(init?.headers).entries()) {
2235
- if (!PER_REQUEST_HEADERS.has(name)) handshake[name] = value;
2236
- }
2237
- handshake["openai-beta"] = CODEX_RESPONSES_WEBSOCKET_BETA;
2238
- const wsUrl = url.replace(/^https:/, "wss:");
2239
- const key = JSON.stringify([wsUrl, Object.entries(handshake).sort()]);
2240
- if ((backoffUntil.get(key) ?? 0) > now()) return await http(input, init);
2241
- const signal = init?.signal ?? null;
2242
- signal?.throwIfAborted();
2243
- let connection = pool.get(key);
2244
- if (connection && (connection.closed || now() - connection.openedAt > maxAgeMs)) {
2245
- if (!connection.busy) retire(connection);
2246
- connection = void 0;
2247
- }
2248
- if (connection?.busy) return await http(input, init);
2249
- if (!connection) {
2250
- try {
2251
- connection = await connect(wsUrl, key, handshake);
2252
- } catch {
2253
- backoffUntil.set(key, now() + handshakeBackoffMs);
2254
- return await http(input, init);
2255
- }
2256
- if (pool.has(key)) {
2257
- const existing = pool.get(key);
2258
- if (!existing.busy && !existing.closed) {
2259
- retire(connection);
2260
- connection = existing;
2261
- } else {
2262
- pool.set(key, connection);
2263
- }
2264
- } else {
2265
- pool.set(key, connection);
2266
- }
2267
- if (connection.busy) return await http(input, init);
2268
- }
2269
- const active = connection;
2270
- active.busy = true;
2271
- if (active.idleTimer) clearTimeout(active.idleTimer);
2272
- active.idleTimer = null;
2273
- return await new Promise((resolve, reject) => {
2274
- const headers = new Headers({ "content-type": "text/event-stream" });
2275
- let controller = null;
2276
- let started = false;
2277
- let finished = false;
2278
- const pending = [];
2279
- const finish = (error) => {
2280
- if (finished) return;
2281
- finished = true;
2282
- signal?.removeEventListener("abort", onAbort);
2283
- if (error !== void 0) {
2284
- retire(active);
2285
- active.busy = false;
2286
- if (started) controller?.error(error);
2287
- else reject(error);
2288
- return;
2289
- }
2290
- release(active);
2291
- try {
2292
- controller?.close();
2293
- } catch {
2294
- }
2295
- };
2296
- const onAbort = () => finish(signal?.reason ?? new Error("Model request aborted"));
2297
- signal?.addEventListener("abort", onAbort, { once: true });
2298
- const stream = new ReadableStream({
2299
- start(streamController) {
2300
- controller = streamController;
2301
- for (const block of pending.splice(0)) streamController.enqueue(block);
2302
- if (finished) streamController.close();
2303
- },
2304
- cancel() {
2305
- if (!finished) finish(new Error("Model response stream cancelled"));
2306
- }
2307
- });
2308
- const begin = (status = 200, errorBody) => {
2309
- started = true;
2310
- if (errorBody !== void 0) {
2311
- headers.set("content-type", "application/json");
2312
- resolve(new Response(errorBody, { status, headers }));
2313
- return;
2314
- }
2315
- resolve(new Response(stream, { status, headers }));
2316
- };
2317
- active.onClose = (error) => finish(error);
2318
- active.onEvent = (event) => {
2319
- if (finished) return;
2320
- const type = typeof event.type === "string" ? event.type : "";
2321
- if (type === RATE_LIMITS_EVENT) {
2322
- if (!started)
2323
- for (const [name, value] of codexRateLimitHeaders(event)) headers.set(name, value);
2324
- return;
2325
- }
2326
- if (type === METADATA_EVENT) {
2327
- if (!started)
2328
- for (const [name, value] of metadataHeaders(event)) headers.set(name, value);
2329
- return;
2330
- }
2331
- if (type === TIMING_EVENT) return;
2332
- if (!started && type === "error" && typeof event.status === "number") {
2333
- for (const [name, value] of metadataHeaders(event)) headers.set(name, value);
2334
- const status = event.status >= 400 && event.status < 600 ? event.status : 500;
2335
- begin(status, JSON.stringify({ error: event.error ?? null }));
2336
- finished = true;
2337
- signal?.removeEventListener("abort", onAbort);
2338
- release(active);
2339
- return;
2340
- }
2341
- if (!started) begin();
2342
- const block = sseBlock(event);
2343
- if (controller) controller.enqueue(block);
2344
- else pending.push(block);
2345
- if (TERMINAL_EVENTS.has(type)) finish();
2346
- };
2347
- try {
2348
- active.socket.send(JSON.stringify({ ...payload, type: "response.create" }));
2349
- } catch (error) {
2350
- finish(error);
2351
- }
2352
- });
2353
- };
2354
- }
2355
-
2356
2420
  // src/mcp-sanitize.ts
2357
2421
  var VALID_TOOL_NAME = /^[a-zA-Z0-9_-]+$/;
2358
2422
  var MAX_TOOL_NAME_LEN = 64;
@@ -3788,6 +3852,7 @@ export {
3788
3852
  CODEX_TOKEN_URL,
3789
3853
  CODEX_TOOL_OUTPUT_SERIALIZATION_ALLOWANCE,
3790
3854
  CODEX_TRANSPORT_ERROR_HEADER,
3855
+ CODEX_TRANSPORT_HEADER,
3791
3856
  CODEX_USAGE_LIMIT_ERROR_TYPE,
3792
3857
  CODEX_WEEKLY_WINDOW_SECONDS,
3793
3858
  CODEX_WHAM_BASE,
@@ -3839,6 +3904,7 @@ export {
3839
3904
  fetchCodexRateLimitResetCredits,
3840
3905
  fetchCodexRealtimeProviderConfig,
3841
3906
  fetchCodexUsage,
3907
+ formatCodexRequestTransport,
3842
3908
  generateCodexSubscriptionImage,
3843
3909
  isCodexAppsCredentialUnavailable,
3844
3910
  isCodexBilledModel,
@@ -3857,6 +3923,7 @@ export {
3857
3923
  parseCodexRateLimitResetCreditsDetails,
3858
3924
  parseCodexRateLimitResetCreditsSummary,
3859
3925
  parseCodexRealtimeV3Event,
3926
+ parseCodexRequestTransport,
3860
3927
  parseCodexUsageHeaders,
3861
3928
  parseIdToken,
3862
3929
  pollDeviceCode,