@openclaw/ai 2026.7.2-beta.4 → 2026.7.2-beta.6
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/{anthropic-CrUDIBpM.mjs → anthropic-CH4UUnZr.mjs} +26 -441
- package/dist/{anthropic-BoTnz8cv.d.mts → anthropic-SrGtwsJu.d.mts} +27 -1
- package/dist/anthropic-usage-DWU-x8MI.mjs +459 -0
- package/dist/{api-registry-BMphkFf1.d.mts → api-registry-DlMgPR39.d.mts} +1 -1
- package/dist/{azure-openai-responses-CbrpVeEv.mjs → azure-openai-responses-CImcwB83.mjs} +4 -4
- package/dist/cache-retention-0x979a5V.mjs +12 -0
- package/dist/deferred-event-buffer-DAvyP7qA.mjs +19 -0
- package/dist/error-coercion-DgxlWC0n.mjs +15 -0
- package/dist/{event-stream-Douf9dob.d.mts → event-stream-YjaPW20U.d.mts} +1 -1
- package/dist/event-stream.d.mts +1 -1
- package/dist/{github-copilot-headers-BsH5cqGj.mjs → github-copilot-headers-NCJtz9i0.mjs} +1 -12
- package/dist/{google-Cs62KA7t.mjs → google-CtSg0iTS.mjs} +3 -3
- package/dist/{google-shared-CMLI-tCZ.mjs → google-shared-DNBz5rcD.mjs} +7 -4
- package/dist/{google-vertex-B4SD3U0f.mjs → google-vertex-31f1uS9L.mjs} +3 -3
- package/dist/{host-WvWBo4h8.d.mts → host-B9GUmcra.d.mts} +2 -2
- package/dist/host-Dog2WQiR.mjs +369 -0
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +3 -3
- package/dist/internal/anthropic.d.mts +16 -62
- package/dist/internal/anthropic.mjs +5 -4
- package/dist/internal/openai.d.mts +260 -2
- package/dist/internal/openai.mjs +7 -5
- package/dist/internal/runtime.d.mts +8 -32
- package/dist/internal/runtime.mjs +7 -6
- package/dist/internal/shared.d.mts +14 -9
- package/dist/internal/shared.mjs +6 -2
- package/dist/{llm-request-activity-CehVkZP-.mjs → llm-request-activity-BjtkplhG.mjs} +1 -19
- package/dist/{mistral-D5Ps7Led.mjs → mistral-CWmpvWYh.mjs} +7 -4
- package/dist/number-coercion-DvG7SNMg.mjs +129 -0
- package/dist/{openai-chatgpt-responses-h0o5yV8Y.mjs → openai-chatgpt-responses-B84Ibtrd.mjs} +33 -29
- package/dist/{openai-completions-exO8NFQf.mjs → openai-completions-DsOxhOD1.mjs} +28 -482
- package/dist/openai-completions-compat-DBWjXoMZ.d.mts +43 -0
- package/dist/openai-prompt-cache-2uo_1OR1.d.mts +7 -0
- package/dist/openai-prompt-cache-mZTCdRPo.mjs +12 -0
- package/dist/openai-reasoning-compat-YgeLncHw.mjs +396 -0
- package/dist/{openai-responses-BHpmtUKo.mjs → openai-responses-BT7A3sLu.mjs} +7 -5
- package/dist/openai-responses-shared-pXl6Wd8S.mjs +392 -0
- package/dist/{openai-responses-shared-CzCurmY1.mjs → openai-responses-stream-internal-Cw5txaGW.mjs} +1609 -1037
- package/dist/{openai-tool-projection-ITOU9bG1.mjs → openai-tool-projection-OhX64DoP.mjs} +26 -11
- package/dist/prompt-cache-stability-Cwcjv_fx.d.mts +13 -0
- package/dist/{provider-error-C4VvV_3t.mjs → provider-error-CAEvRjry.mjs} +8 -2
- package/dist/provider-options-D8bB3z9b.d.mts +144 -0
- package/dist/providers.d.mts +3 -2
- package/dist/providers.mjs +10 -9
- package/dist/reasoning-tag-text-partitioner-CGDyLWUR.mjs +12209 -0
- package/dist/simple-options-9lhRrN73.mjs +50 -0
- package/dist/{src-CXno1H5g.mjs → src-QkygScBs.mjs} +23 -4
- package/dist/stream-first-event-timeout-BBys9hSb.mjs +86 -0
- package/dist/stream-first-event-timeout-DvDeSucC.d.mts +29 -0
- package/dist/tls-certificate-errors-DXSpluKI.mjs +93 -0
- package/dist/tool-result-text-CTpIRbYd.mjs +225 -0
- package/dist/transform-messages-C8mBqZxF.mjs +2 -0
- package/dist/transport-stream-shared-D81p90xq.mjs +297 -0
- package/dist/transports.d.mts +115 -132
- package/dist/transports.mjs +400 -1991
- package/dist/{types-AFwwWium.d.mts → types-bzp5k29J.d.mts} +7 -0
- package/dist/types.d.mts +5 -5
- package/dist/types.mjs +2 -2
- package/dist/{validation-sxvxC8J-.d.mts → validation-B-j7cOYp.d.mts} +1 -1
- package/dist/validation.d.mts +1 -1
- package/package.json +4 -5
- package/dist/host-XYGZcgO8.mjs +0 -98
- package/dist/model-utils-1GiZ2_rr.mjs +0 -64
- package/dist/openai-CoGicoDt.d.mts +0 -332
- package/dist/reasoning-tag-text-partitioner-BlVe67g6.mjs +0 -400
- package/dist/stream-first-event-timeout-DP4xEyBY.mjs +0 -150
- package/dist/system-prompt-cache-boundary-CbHeV4_l.mjs +0 -526
- package/npm-shrinkwrap.json +0 -638
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { a as requiresClaudeMandatoryAdaptiveThinking, l as resolveClaudeNativeThinkingLevelMap } from "./src-QkygScBs.mjs";
|
|
2
|
+
//#region packages/ai/src/model-utils.ts
|
|
3
|
+
/** Calculates and stores model cost fields from token usage and per-million pricing. */
|
|
4
|
+
function calculateCost(model, usage) {
|
|
5
|
+
const cacheWrite1h = Math.min(usage.cacheWrite, Math.max(0, usage.cacheWrite1h ?? 0));
|
|
6
|
+
const cacheWrite5m = usage.cacheWrite - cacheWrite1h;
|
|
7
|
+
usage.cost.input = model.cost.input / 1e6 * usage.input;
|
|
8
|
+
usage.cost.output = model.cost.output / 1e6 * usage.output;
|
|
9
|
+
usage.cost.cacheRead = model.cost.cacheRead / 1e6 * usage.cacheRead;
|
|
10
|
+
usage.cost.cacheWrite = (model.cost.cacheWrite * cacheWrite5m + model.cost.input * 2 * cacheWrite1h) / 1e6;
|
|
11
|
+
usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
|
|
12
|
+
return usage.cost;
|
|
13
|
+
}
|
|
14
|
+
/** Replaces the catalog estimate when the provider reports an authoritative billed total. */
|
|
15
|
+
function applyProviderReportedUsageCost(usage, reportedCost) {
|
|
16
|
+
if (typeof reportedCost !== "number" || !Number.isFinite(reportedCost) || reportedCost < 0) return;
|
|
17
|
+
usage.cost.total = reportedCost;
|
|
18
|
+
usage.cost.totalOrigin = "provider-billed";
|
|
19
|
+
}
|
|
20
|
+
const EXTENDED_THINKING_LEVELS = [
|
|
21
|
+
"off",
|
|
22
|
+
"minimal",
|
|
23
|
+
"low",
|
|
24
|
+
"medium",
|
|
25
|
+
"high",
|
|
26
|
+
"xhigh",
|
|
27
|
+
"max"
|
|
28
|
+
];
|
|
29
|
+
function resolveThinkingLevelMap(model) {
|
|
30
|
+
return model.api === "anthropic-messages" ? resolveClaudeNativeThinkingLevelMap(model) ?? model.thinkingLevelMap : model.thinkingLevelMap;
|
|
31
|
+
}
|
|
32
|
+
/** Returns thinking levels exposed by a reasoning-capable model. */
|
|
33
|
+
function getSupportedThinkingLevels(model) {
|
|
34
|
+
const mandatoryAdaptiveContract = model.api === "anthropic-messages" && requiresClaudeMandatoryAdaptiveThinking(model);
|
|
35
|
+
if (!model.reasoning && !mandatoryAdaptiveContract) return ["off"];
|
|
36
|
+
const thinkingLevelMap = resolveThinkingLevelMap(model);
|
|
37
|
+
return EXTENDED_THINKING_LEVELS.filter((level) => {
|
|
38
|
+
const mapped = thinkingLevelMap?.[level];
|
|
39
|
+
if (mapped === null) return false;
|
|
40
|
+
if (level === "xhigh" || level === "max") return mapped !== void 0;
|
|
41
|
+
return true;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/** Clamps a requested thinking level to the closest supported level for a model. */
|
|
45
|
+
function clampThinkingLevel(model, level) {
|
|
46
|
+
const availableLevels = getSupportedThinkingLevels(model);
|
|
47
|
+
if (availableLevels.includes(level)) return level;
|
|
48
|
+
const requestedIndex = EXTENDED_THINKING_LEVELS.indexOf(level);
|
|
49
|
+
if (requestedIndex === -1) return availableLevels[0] ?? "off";
|
|
50
|
+
const thinkingLevelMap = resolveThinkingLevelMap(model);
|
|
51
|
+
if ((level === "xhigh" || level === "max") && thinkingLevelMap?.[level] === null) {
|
|
52
|
+
for (const candidate of EXTENDED_THINKING_LEVELS.slice(0, requestedIndex).toReversed()) if (availableLevels.includes(candidate)) return candidate;
|
|
53
|
+
}
|
|
54
|
+
for (const candidate of EXTENDED_THINKING_LEVELS.slice(requestedIndex)) if (availableLevels.includes(candidate)) return candidate;
|
|
55
|
+
for (const candidate of EXTENDED_THINKING_LEVELS.slice(0, requestedIndex).toReversed()) if (availableLevels.includes(candidate)) return candidate;
|
|
56
|
+
return availableLevels[0] ?? "off";
|
|
57
|
+
}
|
|
58
|
+
/** Compares model identity by provider and id. */
|
|
59
|
+
function modelsAreEqual(a, b) {
|
|
60
|
+
if (!a || !b) return false;
|
|
61
|
+
return a.id === b.id && a.provider === b.provider;
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region packages/normalization-core/src/number-coercion.ts
|
|
65
|
+
/** Returns a number only when the input is already finite. */
|
|
66
|
+
function asFiniteNumber(value) {
|
|
67
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
68
|
+
}
|
|
69
|
+
/** Returns a finite number only when it satisfies the supplied inclusive/exclusive bounds. */
|
|
70
|
+
function asFiniteNumberInRange(value, range) {
|
|
71
|
+
const number = asFiniteNumber(value);
|
|
72
|
+
if (number === void 0) return;
|
|
73
|
+
if (range.min !== void 0) {
|
|
74
|
+
if (range.minExclusive ? number <= range.min : number < range.min) return;
|
|
75
|
+
}
|
|
76
|
+
if (range.max !== void 0) {
|
|
77
|
+
if (range.maxExclusive ? number >= range.max : number > range.max) return;
|
|
78
|
+
}
|
|
79
|
+
return number;
|
|
80
|
+
}
|
|
81
|
+
function normalizeNumericString(value) {
|
|
82
|
+
const trimmed = value.trim();
|
|
83
|
+
return trimmed ? trimmed : void 0;
|
|
84
|
+
}
|
|
85
|
+
/** Parses only safe integer numbers or base-10 integer strings. */
|
|
86
|
+
function parseStrictInteger(value) {
|
|
87
|
+
if (typeof value === "number") return Number.isSafeInteger(value) ? value : void 0;
|
|
88
|
+
if (typeof value !== "string") return;
|
|
89
|
+
const normalized = normalizeNumericString(value);
|
|
90
|
+
if (!normalized || !/^[+-]?\d+$/.test(normalized)) return;
|
|
91
|
+
const parsed = Number(normalized);
|
|
92
|
+
return Number.isSafeInteger(parsed) ? parsed : void 0;
|
|
93
|
+
}
|
|
94
|
+
/** Parses only finite decimal/scientific string tokens, rejecting partial numbers. */
|
|
95
|
+
function parseStrictFiniteNumber(value) {
|
|
96
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
|
|
97
|
+
if (typeof value !== "string") return;
|
|
98
|
+
const normalized = normalizeNumericString(value);
|
|
99
|
+
if (!normalized || !/^[+-]?(?:(?:\d+\.?\d*)|(?:\.\d+))(?:e[+-]?\d+)?$/i.test(normalized)) return;
|
|
100
|
+
const parsed = Number(normalized);
|
|
101
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
102
|
+
}
|
|
103
|
+
/** Conservative upper bound for Node timer delays. */
|
|
104
|
+
const MAX_TIMER_TIMEOUT_MS = 2147e6;
|
|
105
|
+
/** Clamps finite millisecond values into the Node-safe timer range. */
|
|
106
|
+
function clampTimerTimeoutMs(valueMs, minMs = 1) {
|
|
107
|
+
const value = asFiniteNumber(valueMs);
|
|
108
|
+
if (value === void 0) return;
|
|
109
|
+
return Math.min(Math.max(Math.floor(value), Math.max(1, Math.floor(minMs))), MAX_TIMER_TIMEOUT_MS);
|
|
110
|
+
}
|
|
111
|
+
/** Resolves arbitrary timeout input with fallback and minimum timer bounds. */
|
|
112
|
+
function resolveTimerTimeoutMs(valueMs, fallbackMs, minMs = 1) {
|
|
113
|
+
const value = asFiniteNumber(valueMs) ?? asFiniteNumber(fallbackMs);
|
|
114
|
+
const min = Math.max(0, Math.floor(minMs));
|
|
115
|
+
if (value === void 0) return min;
|
|
116
|
+
return Math.min(Math.max(Math.floor(value), min), MAX_TIMER_TIMEOUT_MS);
|
|
117
|
+
}
|
|
118
|
+
/** Parses strict positive integer values from numbers or strings. */
|
|
119
|
+
function parseStrictPositiveInteger(value) {
|
|
120
|
+
const parsed = parseStrictInteger(value);
|
|
121
|
+
return parsed !== void 0 && parsed > 0 ? parsed : void 0;
|
|
122
|
+
}
|
|
123
|
+
/** Parses strict non-negative integer values from numbers or strings. */
|
|
124
|
+
function parseStrictNonNegativeInteger(value) {
|
|
125
|
+
const parsed = parseStrictInteger(value);
|
|
126
|
+
return parsed !== void 0 && parsed >= 0 ? parsed : void 0;
|
|
127
|
+
}
|
|
128
|
+
//#endregion
|
|
129
|
+
export { parseStrictPositiveInteger as a, calculateCost as c, modelsAreEqual as d, parseStrictNonNegativeInteger as i, clampThinkingLevel as l, clampTimerTimeoutMs as n, resolveTimerTimeoutMs as o, parseStrictFiniteNumber as r, applyProviderReportedUsageCost as s, asFiniteNumberInRange as t, getSupportedThinkingLevels as u };
|
package/dist/{openai-chatgpt-responses-h0o5yV8Y.mjs → openai-chatgpt-responses-B84Ibtrd.mjs}
RENAMED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { n as getEnvApiKey } from "./env-api-keys-DrgeBuva.mjs";
|
|
2
2
|
import { i as formatThrownValue, n as createAssistantMessageDiagnostic, t as appendAssistantMessageDiagnostic } from "./diagnostics-COpOtRwq.mjs";
|
|
3
3
|
import { t as AssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
|
|
4
|
-
import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-
|
|
5
|
-
import {
|
|
4
|
+
import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-Dog2WQiR.mjs";
|
|
5
|
+
import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
|
|
6
|
+
import { d as stripSystemPromptCacheBoundary } from "./tool-result-text-CTpIRbYd.mjs";
|
|
7
|
+
import { t as toErrorObject } from "./error-coercion-DgxlWC0n.mjs";
|
|
8
|
+
import { n as clampTimerTimeoutMs, o as resolveTimerTimeoutMs } from "./number-coercion-DvG7SNMg.mjs";
|
|
9
|
+
import { parseRetryAfterHttpDateMs } from "./internal/retry-after.mjs";
|
|
10
|
+
import { d as transportAbortError } from "./transport-stream-shared-D81p90xq.mjs";
|
|
11
|
+
import { _t as supportsOpenAITemperature, n as processResponsesStream } from "./openai-responses-stream-internal-Cw5txaGW.mjs";
|
|
12
|
+
import { i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-BBys9hSb.mjs";
|
|
6
13
|
import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
|
|
14
|
+
import { n as buildBaseOptions } from "./simple-options-9lhRrN73.mjs";
|
|
15
|
+
import { i as resolveResponsesReasoningEffort, n as convertResponsesMessages, o as convertResponsesToolPayload } from "./openai-responses-shared-pXl6Wd8S.mjs";
|
|
7
16
|
import { i as registerSessionResourceCleanup, n as resolveOpenAICodexAccountId } from "./openai-chatgpt-jwt-DhAAzLkj.mjs";
|
|
8
|
-
import { d as resolveTimerTimeoutMs, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, s as clampTimerTimeoutMs, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-DP4xEyBY.mjs";
|
|
9
17
|
import { t as createSseByteGuard } from "./streaming-byte-guard-BrbkbwUu.mjs";
|
|
10
|
-
import {
|
|
11
|
-
import { L as supportsOpenAITemperature, a as resolveResponsesReasoningEffort, i as processResponsesStream, n as convertResponsesMessages, s as convertResponsesToolPayload } from "./openai-responses-shared-CzCurmY1.mjs";
|
|
12
|
-
import { a as clampOpenAIPromptCacheKey } from "./openai-tool-projection-ITOU9bG1.mjs";
|
|
18
|
+
import { t as inspectTlsCertificateError } from "./tls-certificate-errors-DXSpluKI.mjs";
|
|
13
19
|
//#region packages/ai/src/internal/retry-sleep.ts
|
|
14
20
|
function sleepWithAbort(ms, signal) {
|
|
15
21
|
return new Promise((resolve, reject) => {
|
|
@@ -144,10 +150,6 @@ const streamOpenAICodexResponses = (model, context, options) => {
|
|
|
144
150
|
const nextBody = await options?.onPayload?.(body, model);
|
|
145
151
|
if (nextBody !== void 0) body = nextBody;
|
|
146
152
|
const sessionId = clampOpenAIPromptCacheKey(options?.sessionId);
|
|
147
|
-
const websocketRequestId = sessionId || createCodexRequestId();
|
|
148
|
-
const sseHeaders = buildSSEHeaders(modelHeaders, optionHeaders, accountId, apiKey, sessionId);
|
|
149
|
-
const websocketHeaders = buildWebSocketHeaders(modelHeaders, optionHeaders, accountId, apiKey, websocketRequestId);
|
|
150
|
-
const bodyJson = JSON.stringify(body);
|
|
151
153
|
requestTimeoutMs = resolveRequestTimeoutMs(options);
|
|
152
154
|
requestTimeoutSignal = buildRequestSignal(options?.signal, requestTimeoutMs);
|
|
153
155
|
firstEventAbort = createFirstStreamEventAbortController(requestTimeoutSignal);
|
|
@@ -159,6 +161,7 @@ const streamOpenAICodexResponses = (model, context, options) => {
|
|
|
159
161
|
const transport = options?.transport || "auto";
|
|
160
162
|
const websocketDisabledForSession = transport === "auto" && isWebSocketSseFallbackActive(options?.sessionId);
|
|
161
163
|
if (transport !== "sse" && !websocketDisabledForSession) {
|
|
164
|
+
const websocketHeaders = buildWebSocketHeaders(modelHeaders, optionHeaders, accountId, apiKey, sessionId || createCodexRequestId());
|
|
162
165
|
let websocketStarted = false;
|
|
163
166
|
let retriedWebSocketConnectionLimit = false;
|
|
164
167
|
while (true) {
|
|
@@ -167,7 +170,7 @@ const streamOpenAICodexResponses = (model, context, options) => {
|
|
|
167
170
|
await processWebSocketStream(resolveCodexWebSocketUrl(model.baseUrl), body, websocketHeaders, output, stream, model, () => {
|
|
168
171
|
websocketStarted = true;
|
|
169
172
|
}, requestOptions, firstEventAbort.abort);
|
|
170
|
-
if (activeSignal?.aborted) throw
|
|
173
|
+
if (activeSignal?.aborted) throw transportAbortError(activeSignal);
|
|
171
174
|
stream.push({
|
|
172
175
|
type: "done",
|
|
173
176
|
reason: output.stopReason,
|
|
@@ -188,7 +191,7 @@ const streamOpenAICodexResponses = (model, context, options) => {
|
|
|
188
191
|
fallbackTransport: transport === "auto" && !websocketStarted ? "sse" : void 0,
|
|
189
192
|
eventsEmitted: websocketStarted,
|
|
190
193
|
phase: websocketStarted ? "after_message_stream_start" : "before_message_stream_start",
|
|
191
|
-
requestBytes: new TextEncoder().encode(
|
|
194
|
+
requestBytes: new TextEncoder().encode(JSON.stringify(body)).byteLength
|
|
192
195
|
}));
|
|
193
196
|
if (transport === "auto" && options?.sessionId) websocketSseFallbackSessions.add(options.sessionId);
|
|
194
197
|
if (websocketStarted || transport !== "auto") throw error;
|
|
@@ -196,6 +199,8 @@ const streamOpenAICodexResponses = (model, context, options) => {
|
|
|
196
199
|
}
|
|
197
200
|
}
|
|
198
201
|
}
|
|
202
|
+
const sseHeaders = buildSSEHeaders(modelHeaders, optionHeaders, accountId, apiKey, sessionId);
|
|
203
|
+
const bodyJson = JSON.stringify(body);
|
|
199
204
|
const compressedBody = model.provider === "openai" && !sseHeaders.has("content-encoding") ? compressRequestBodyZstd(bodyJson) : null;
|
|
200
205
|
if (compressedBody) sseHeaders.set("content-encoding", "zstd");
|
|
201
206
|
const sseBody = compressedBody ?? bodyJson;
|
|
@@ -203,7 +208,7 @@ const streamOpenAICodexResponses = (model, context, options) => {
|
|
|
203
208
|
let lastError;
|
|
204
209
|
const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
205
210
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
206
|
-
if (activeSignal?.aborted) throw
|
|
211
|
+
if (activeSignal?.aborted) throw transportAbortError(activeSignal);
|
|
207
212
|
let attemptResponse;
|
|
208
213
|
let errorText;
|
|
209
214
|
try {
|
|
@@ -226,8 +231,9 @@ const streamOpenAICodexResponses = (model, context, options) => {
|
|
|
226
231
|
if (error.name === "AbortError" || error.message === "Request was aborted") throw new Error("Request was aborted", { cause: error });
|
|
227
232
|
if (error.name === "TimeoutError" && requestTimeoutMs !== void 0) throw new Error(`Request timed out after ${requestTimeoutMs}ms`, { cause: error });
|
|
228
233
|
}
|
|
229
|
-
|
|
230
|
-
|
|
234
|
+
const tlsCertificateError = inspectTlsCertificateError(error);
|
|
235
|
+
lastError = toErrorObject(error, String(error));
|
|
236
|
+
if (attempt < maxRetries && !lastError.message.includes("usage limit") && !tlsCertificateError) {
|
|
231
237
|
await sleepWithAbort(BASE_DELAY_MS * 2 ** attempt, activeSignal);
|
|
232
238
|
continue;
|
|
233
239
|
}
|
|
@@ -247,7 +253,7 @@ const streamOpenAICodexResponses = (model, context, options) => {
|
|
|
247
253
|
partial: output
|
|
248
254
|
});
|
|
249
255
|
await processStream(response, output, stream, model, options, firstEventAbort.abort);
|
|
250
|
-
if (activeSignal?.aborted) throw
|
|
256
|
+
if (activeSignal?.aborted) throw transportAbortError(activeSignal);
|
|
251
257
|
stream.push({
|
|
252
258
|
type: "done",
|
|
253
259
|
reason: output.stopReason,
|
|
@@ -357,6 +363,7 @@ async function processStream(response, output, stream, model, options, abortFirs
|
|
|
357
363
|
firstEventTimeoutMs: getFirstStreamEventTimeoutMs(options),
|
|
358
364
|
abortFirstEventStream,
|
|
359
365
|
onFirstEventTimeout: getFirstStreamEventTimeoutHandler(options),
|
|
366
|
+
signal: options?.signal,
|
|
360
367
|
resolveServiceTier: resolveCodexServiceTier,
|
|
361
368
|
applyServiceTierPricing: (usage, serviceTier) => applyServiceTierPricing(usage, serviceTier, model)
|
|
362
369
|
});
|
|
@@ -549,12 +556,15 @@ function closeWebSocketSilently(socket, code = 1e3, reason = "done") {
|
|
|
549
556
|
socket.close(code, reason);
|
|
550
557
|
} catch {}
|
|
551
558
|
}
|
|
559
|
+
function deleteOwnedWebSocketSession(sessionId, entry) {
|
|
560
|
+
if (websocketSessionCache.get(sessionId) === entry) websocketSessionCache.delete(sessionId);
|
|
561
|
+
}
|
|
552
562
|
function scheduleSessionWebSocketExpiry(sessionId, entry) {
|
|
553
563
|
if (entry.idleTimer) clearTimeout(entry.idleTimer);
|
|
554
564
|
entry.idleTimer = setTimeout(() => {
|
|
555
565
|
if (entry.busy) return;
|
|
556
566
|
closeWebSocketSilently(entry.socket, 1e3, "idle_timeout");
|
|
557
|
-
|
|
567
|
+
deleteOwnedWebSocketSession(sessionId, entry);
|
|
558
568
|
}, SESSION_WEBSOCKET_CACHE_TTL_MS);
|
|
559
569
|
}
|
|
560
570
|
async function connectWebSocket(url, headers, signal) {
|
|
@@ -645,7 +655,7 @@ async function acquireWebSocket(url, headers, sessionId, signal) {
|
|
|
645
655
|
release: ({ keep } = {}) => {
|
|
646
656
|
if (!keep || !isWebSocketReusable(cached.socket)) {
|
|
647
657
|
closeWebSocketSilently(cached.socket);
|
|
648
|
-
|
|
658
|
+
deleteOwnedWebSocketSession(sessionId, cached);
|
|
649
659
|
return;
|
|
650
660
|
}
|
|
651
661
|
cached.busy = false;
|
|
@@ -681,7 +691,7 @@ async function acquireWebSocket(url, headers, sessionId, signal) {
|
|
|
681
691
|
if (!keep || !isWebSocketReusable(entry.socket)) {
|
|
682
692
|
closeWebSocketSilently(entry.socket);
|
|
683
693
|
if (entry.idleTimer) clearTimeout(entry.idleTimer);
|
|
684
|
-
|
|
694
|
+
deleteOwnedWebSocketSession(sessionId, entry);
|
|
685
695
|
return;
|
|
686
696
|
}
|
|
687
697
|
entry.busy = false;
|
|
@@ -794,7 +804,7 @@ async function* parseWebSocket(socket, signal) {
|
|
|
794
804
|
signal?.addEventListener("abort", onAbort);
|
|
795
805
|
try {
|
|
796
806
|
while (true) {
|
|
797
|
-
if (signal?.aborted) throw
|
|
807
|
+
if (signal?.aborted) throw transportAbortError(signal);
|
|
798
808
|
const next = queue.shift();
|
|
799
809
|
if (next !== void 0) {
|
|
800
810
|
yield next;
|
|
@@ -805,7 +815,7 @@ async function* parseWebSocket(socket, signal) {
|
|
|
805
815
|
pending = resolve;
|
|
806
816
|
});
|
|
807
817
|
}
|
|
808
|
-
if (failed) throw
|
|
818
|
+
if (failed) throw toErrorObject(failed, "Non-Error thrown");
|
|
809
819
|
if (!sawCompletion) throw new Error("WebSocket stream closed before response.completed");
|
|
810
820
|
} finally {
|
|
811
821
|
socket.removeEventListener("message", onMessage);
|
|
@@ -867,7 +877,7 @@ async function processWebSocketStream(url, body, headers, output, stream, model,
|
|
|
867
877
|
const fullBody = body;
|
|
868
878
|
const requestBody = useCachedContext && entry ? buildCachedWebSocketRequestBody(entry, fullBody) : fullBody;
|
|
869
879
|
try {
|
|
870
|
-
if (options?.signal?.aborted) throw
|
|
880
|
+
if (options?.signal?.aborted) throw transportAbortError(options.signal);
|
|
871
881
|
socket.send(JSON.stringify({
|
|
872
882
|
type: "response.create",
|
|
873
883
|
...requestBody
|
|
@@ -877,6 +887,7 @@ async function processWebSocketStream(url, body, headers, output, stream, model,
|
|
|
877
887
|
firstEventTimeoutMs: getFirstStreamEventTimeoutMs(options),
|
|
878
888
|
abortFirstEventStream,
|
|
879
889
|
onFirstEventTimeout: getFirstStreamEventTimeoutHandler(options),
|
|
890
|
+
signal: options?.signal,
|
|
880
891
|
resolveServiceTier: resolveCodexServiceTier,
|
|
881
892
|
applyServiceTierPricing: (usage, serviceTier) => applyServiceTierPricing(usage, serviceTier, model)
|
|
882
893
|
});
|
|
@@ -1000,12 +1011,5 @@ function buildWebSocketHeaders(initHeaders, additionalHeaders, accountId, token,
|
|
|
1000
1011
|
headers.set("session_id", requestId);
|
|
1001
1012
|
return headers;
|
|
1002
1013
|
}
|
|
1003
|
-
function toLintErrorObject(value, fallbackMessage) {
|
|
1004
|
-
if (value instanceof Error) return value;
|
|
1005
|
-
if (typeof value === "string") return new Error(value);
|
|
1006
|
-
const error = new Error(fallbackMessage, { cause: value });
|
|
1007
|
-
if (typeof value === "object" && value !== null || typeof value === "function") Object.assign(error, value);
|
|
1008
|
-
return error;
|
|
1009
|
-
}
|
|
1010
1014
|
//#endregion
|
|
1011
1015
|
export { closeOpenAICodexWebSocketSessions, extractOpenAICodexAccountId, parseSSEForTest, resetOpenAICodexWebSocketStateForTest, streamOpenAICodexResponses, streamSimpleOpenAICodexResponses };
|