@openclaw/ai 2026.9.7 → 2026.10.1-beta.1
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 +4 -1
- package/dist/{anthropic-Cw2pgccz.mjs → anthropic-CZv6XFER.mjs} +52 -147
- package/dist/{anthropic-payload-policy-NIPVYXPq.d.mts → anthropic-payload-policy-BhCcgNdm.d.mts} +7 -4
- package/dist/{anthropic-stream-reducer-D9MCkl8Z.mjs → anthropic-stream-reducer-BQ1tjd7x.mjs} +369 -233
- package/dist/{api-registry-D-nbmSqr.d.mts → api-registry-DpU0Rj-I.d.mts} +4 -4
- package/dist/{provider-transcript-transform-JbFbHV8h.mjs → assistant-output-OLm-Oln0.mjs} +17 -17
- package/dist/{assistant-text-phase-C20rxWwP.mjs → assistant-text-phase-Bl1aDCB7.mjs} +2 -8
- package/dist/{azure-openai-responses-BwT3-X8P.mjs → azure-openai-responses-DH7bd3QT.mjs} +12 -17
- package/dist/{azure-openai-responses-client-compat-C7K7QfUE.mjs → azure-openai-responses-client-compat-D0dvJMbZ.mjs} +3 -10
- package/dist/{base64-C1PsYcRQ.mjs → base64-C8CdcsjU.mjs} +3 -45
- package/dist/cloudflare-5qSGvIUH.mjs +39 -0
- package/dist/{diagnostics-CJaB6g8J.mjs → diagnostics-Caj-4RBA.mjs} +19 -37
- package/dist/diagnostics.d.mts +4 -4
- package/dist/diagnostics.mjs +2 -2
- package/dist/{event-stream-vd9UnCAU.mjs → event-stream-C5AbCAaZ.mjs} +29 -1
- package/dist/event-stream-DqDQWqiy.d.mts +1 -0
- package/dist/{event-stream-DOPFYVqs.d.mts → event-stream-DrRM_90c.d.mts} +1 -1
- package/dist/event-stream.d.mts +2 -2
- package/dist/event-stream.mjs +1 -1
- package/dist/{github-copilot-request-facts-BTEBMeOv.mjs → github-copilot-request-facts-DEE6gcB9.mjs} +3 -1
- package/dist/{google-BfapkS_K.mjs → google-1WLOtb8w.mjs} +12 -9
- package/dist/{google-interactions-DW3iXzjc.mjs → google-interactions-wrnE6MLw.mjs} +39 -49
- package/dist/{google-messages-CtjVtVot.mjs → google-messages-BwPPycw6.mjs} +11 -17
- package/dist/{google-shared-Y2YfotEu.mjs → google-shared-Eql1OMPU.mjs} +5 -6
- package/dist/{google-vertex-Dov4kBWu.mjs → google-vertex-0LrlRoO3.mjs} +11 -11
- package/dist/{host-rxlNaBwm.d.mts → host-BinBeGcQ.d.mts} +12 -4
- package/dist/{host-CHi3X87F.mjs → host-DCW52iHe.mjs} +57 -9
- package/dist/{host-policy-BOAwRg_M.mjs → host-policy-B3jc4Rpn.mjs} +9 -2
- package/dist/{index-D6KsSE74.d.mts → index-a8e_oKnu.d.mts} +7 -5
- package/dist/index.d.mts +23 -7
- package/dist/index.mjs +7 -7
- package/dist/internal/anthropic.d.mts +6 -6
- package/dist/internal/anthropic.mjs +5 -5
- package/dist/internal/google-model-family.mjs +1 -1
- package/dist/internal/openai-completions-compat.d.mts +1 -1
- package/dist/internal/openai-completions-compat.mjs +1 -1
- package/dist/internal/openai-responses-payload-policy.d.mts +1 -1
- package/dist/internal/openai-responses-payload-policy.mjs +2 -2
- package/dist/internal/openai.d.mts +14 -10
- package/dist/internal/openai.mjs +12 -12
- package/dist/internal/runtime.d.mts +18 -9
- package/dist/internal/runtime.mjs +9 -9
- package/dist/internal/shared.d.mts +6 -4
- package/dist/internal/shared.mjs +6 -6
- package/dist/internal/tool-schema.mjs +1 -1
- package/dist/json-schema-Bp07Qui3.mjs +22 -0
- package/dist/{llm-request-activity-BjtkplhG.mjs → llm-request-activity-D8f_oxHj.mjs} +1 -2
- package/dist/{mistral-RS6mboC-.mjs → mistral-DSt4vQAO.mjs} +18 -29
- package/dist/number-coercion-V8-BhME4.mjs +47 -0
- package/dist/{openai-chatgpt-responses-CYbidtrn.mjs → openai-chatgpt-responses-BC2x0Oqx.mjs} +215 -164
- package/dist/openai-completions-DNyHnXKg.mjs +25 -0
- package/dist/{openai-completions-compat-qJjmqQ71.d.mts → openai-completions-compat-BYdYpXhU.d.mts} +3 -3
- package/dist/{openai-completions-compat-BOVWBZDn.mjs → openai-completions-compat-BdmlhD4u.mjs} +30 -23
- package/dist/{openai-completions-stream-CDCuw3DP.mjs → openai-completions-transport-DWM2mQDB.mjs} +389 -76
- package/dist/{openai-prompt-cache-CouErLh7.d.mts → openai-prompt-cache-45-AH_xv.d.mts} +2 -2
- package/dist/{openai-prompt-cache-D2V7MqR7.mjs → openai-prompt-cache-I8YQTzf8.mjs} +1 -1
- package/dist/{openai-responses-compaction-replay-DiYn-gFM.d.mts → openai-responses-compaction-replay-BClApUIf.d.mts} +4 -4
- package/dist/{openai-responses-compaction-window-UNK1GDpy.mjs → openai-responses-compaction-window-m878aVpU.mjs} +25 -83
- package/dist/{openai-reasoning-effort-ConhwkeX.mjs → openai-responses-contracts-BKu8O7l4.mjs} +106 -7
- package/dist/{openai-responses-contracts-D1iZ0njF.d.mts → openai-responses-contracts-Br5IIw_h.d.mts} +16 -5
- package/dist/openai-responses-prompt-observer-internal-CCg7B6l4.mjs +32 -0
- package/dist/{openai-responses-shared-DL4ulQn7.mjs → openai-responses-shared-C7oVyjED.mjs} +297 -312
- package/dist/{openai-responses-terminal-usage-BE7lf7nW.d.mts → openai-responses-terminal-usage-DgImcyJu.d.mts} +2 -2
- package/dist/{openai-responses-CKCBEc2W.mjs → openai-responses-uZ5oWSp7.mjs} +12 -21
- package/dist/{openai-tool-schema-vsl-cE-n.mjs → openai-tool-schema-DYNePiF8.mjs} +66 -36
- package/dist/{openai-transport-params-BwlpzX-2.mjs → openai-transport-params-JFsnIyto.mjs} +25 -30
- package/dist/openai-web-search-tools-Cfu0uLyN.mjs +14 -0
- package/dist/{positive-integer-CjN5OJbH.mjs → positive-integer-CwLi8LUL.mjs} +1 -1
- package/dist/{provider-error-CwT_j2v0.mjs → provider-error-DQBE1bUQ.mjs} +17 -28
- package/dist/{provider-options-Df7ov0K1.d.mts → provider-options-D5ABCV_l.d.mts} +2 -2
- package/dist/{provider-replay-context-DsyI5jOP.mjs → provider-replay-context-C7Bmi84a.mjs} +6 -2
- package/dist/{provider-transport-turn-state-BheUi_hl.mjs → provider-transport-turn-state-_M2kLdUE.mjs} +25 -3
- package/dist/{provider-types-d4XnoZMd.d.mts → provider-types-F8Mqc9Ma.d.mts} +3 -3
- package/dist/provider-types.d.mts +6 -6
- package/dist/providers.d.mts +2 -2
- package/dist/providers.mjs +14 -26
- package/dist/{reasoning-tag-text-partitioner-B6FIIBt6.mjs → reasoning-tag-text-partitioner-Ju9VpUGl.mjs} +23 -37
- package/dist/required-api-key-D4kn3252.mjs +9 -0
- package/dist/sanitize-unicode-CjDG6jJx.d.mts +5 -0
- package/dist/{session-affinity-Bcunsn4I.mjs → session-affinity-DA4WHv1h.mjs} +2 -6
- package/dist/session-resources-D1wgDQ8C.mjs +40 -0
- package/dist/{simple-options-CGAkCwtM.mjs → simple-options-BkKTXxhp.mjs} +7 -11
- package/dist/{src-H4aXcFuX.mjs → src-B0NIt2UK.mjs} +7 -4
- package/dist/stream-DSdzKsDK.mjs +275 -0
- package/dist/{stream-first-event-timeout-B9o0S4SZ.mjs → stream-first-event-timeout-D9ZmL_s9.mjs} +3 -3
- package/dist/{string-coerce-fsri9iCu.mjs → string-coerce-CtgOVOSv.mjs} +5 -1
- package/dist/{string-normalization-J9ZiLfGO.mjs → string-normalization-PN10hf6d.mjs} +1 -1
- package/dist/{transport-utils-C-4bf2Ok.mjs → text-signature-MLwfi6fq.mjs} +18 -18
- package/dist/{transport-stream-shared-yYhXa4kX.d.mts → transport-stream-shared-BcAKh2XH.d.mts} +6 -19
- package/dist/{transport-stream-shared-Dh5qKJ8e.mjs → transport-stream-shared-CxXXz_Dd.mjs} +171 -56
- package/dist/transports.d.mts +22 -23
- package/dist/transports.mjs +251 -495
- package/dist/types-BuiEBM3u.d.mts +1 -0
- package/dist/types-CQc6JNG4.mjs +69 -0
- package/dist/{types-CLLR3eB4.d.mts → types-DvzmWW8J.d.mts} +58 -6
- package/dist/types.d.mts +6 -6
- package/dist/types.mjs +5 -5
- package/dist/usage-CJH5D6Ea.mjs +19 -0
- package/dist/{validation-Cat2wQsc.d.mts → validation-B3lQt_VE.d.mts} +1 -1
- package/dist/{validation-BFZc40Ig.mjs → validation-DbqlIfDn.mjs} +15 -30
- package/dist/validation.d.mts +1 -1
- package/dist/validation.mjs +1 -1
- package/package.json +4 -4
- package/dist/cache-retention-0x979a5V.mjs +0 -12
- package/dist/event-stream-CMQfX_yr.d.mts +0 -1
- package/dist/github-copilot-headers-B37TB3rB.mjs +0 -30
- package/dist/openai-completions-D14ihPYk.mjs +0 -188
- package/dist/openai-provider-client-CwfsGBbA.mjs +0 -24
- package/dist/openai-responses-contracts-CLxnqS9p.mjs +0 -81
- package/dist/openai-responses-prompt-observer-internal-iAqLb4tk.mjs +0 -198
- package/dist/sanitize-unicode-BZiVbGwK.d.mts +0 -24
- package/dist/session-resources-CkR4WWy1.mjs +0 -21
- package/dist/stream-DDsCBgd-.mjs +0 -68
- package/dist/types-CB-_vNyI.d.mts +0 -1
- package/dist/types-LFWwv0cF.mjs +0 -8
package/dist/{openai-chatgpt-responses-CYbidtrn.mjs → openai-chatgpt-responses-BC2x0Oqx.mjs}
RENAMED
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
import { i as formatThrownValue, n as createAssistantMessageDiagnostic, t as appendAssistantMessageDiagnostic } from "./diagnostics-DzrF1h4J.mjs";
|
|
2
|
-
import { t as AssistantMessageEventStream } from "./event-stream-
|
|
2
|
+
import { t as AssistantMessageEventStream } from "./event-stream-C5AbCAaZ.mjs";
|
|
3
3
|
import { o as isRecord } from "./record-coerce-CNDovvft.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
4
|
+
import { r as clampPositiveTimerTimeoutMs } from "./number-coercion-V8-BhME4.mjs";
|
|
5
|
+
import { E as headersToRecord, a as resolveAiTransportHeaderSentinels, r as getAiTransportHost } from "./host-DCW52iHe.mjs";
|
|
6
|
+
import { D as supportsOpenAITemperature, h as responsesPromptObserver } from "./openai-responses-contracts-BKu8O7l4.mjs";
|
|
7
|
+
import { r as registerSessionResourceCleanup } from "./session-resources-D1wgDQ8C.mjs";
|
|
8
|
+
import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-I8YQTzf8.mjs";
|
|
9
|
+
import { _ as extractErrorCodeOrErrno, o as WEBSOCKET_NON_RETRYABLE_CLOSE_ERROR_CODE, v as toErrorObject } from "./diagnostics-Caj-4RBA.mjs";
|
|
10
|
+
import { n as MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE } from "./text-signature-MLwfi6fq.mjs";
|
|
10
11
|
import { parseRetryAfterHeadersSeconds } from "./internal/retry-after.mjs";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { n as
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import { A as recordResponsesContextUsage, P as convertProviderResponsesMessages, S as isInvalidEncryptedContentError, T as ResponsesStreamFailure, Z as suppressOpenAIResponsesCompaction, b as commitResponsesEncryptedContentAttempt, i as convertResponsesToolPayload, n as applyResponsesServiceTierPricing, o as readOpenAIMisalignmentReview,
|
|
12
|
+
import { c as resolveOpenAIResponsesTextFormat } from "./openai-completions-compat-BdmlhD4u.mjs";
|
|
13
|
+
import { n as buildManagedModelFetch } from "./host-policy-B3jc4Rpn.mjs";
|
|
14
|
+
import { S as withProviderResponseHook, b as transportAbortError, h as notifyProviderStreamOpened, n as assignTransportErrorDetails } from "./transport-stream-shared-CxXXz_Dd.mjs";
|
|
15
|
+
import { C as stripSystemPromptCacheBoundary, n as buildBaseOptions } from "./simple-options-BkKTXxhp.mjs";
|
|
16
|
+
import { b as createOpenAIResponseHook, g as resolveOpenAISimpleReasoningEffort, h as resolveOpenAIRequestReasoning, x as createResponseModelTracker, y as createOpenAIProviderAcceptanceHook } from "./openai-transport-params-JFsnIyto.mjs";
|
|
17
|
+
import { t as createAssistantOutput } from "./assistant-output-OLm-Oln0.mjs";
|
|
18
|
+
import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-D9ZmL_s9.mjs";
|
|
19
|
+
import { A as recordResponsesContextUsage, J as buildOpenAIResponsesReasoningReplayMetadata, P as convertProviderResponsesMessages, S as isInvalidEncryptedContentError, T as ResponsesStreamFailure, Z as suppressOpenAIResponsesCompaction, b as commitResponsesEncryptedContentAttempt, i as convertResponsesToolPayload, n as applyResponsesServiceTierPricing, o as readOpenAIMisalignmentReview, s as processResponsesStream, w as resolveNextResponsesEncryptedContentAttempt } from "./openai-responses-shared-C7oVyjED.mjs";
|
|
19
20
|
import { t as createSseByteGuard } from "./streaming-byte-guard-CC-HMn_u.mjs";
|
|
20
|
-
import {
|
|
21
|
-
import { i as resolveOpenAIResponsesTextFormat, t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal-iAqLb4tk.mjs";
|
|
21
|
+
import { t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal-CCg7B6l4.mjs";
|
|
22
22
|
import { n as withResponsesRequestAcceptance, t as responsesRequestLifecycle } from "./openai-responses-request-lifecycle-Fsag-IGZ.mjs";
|
|
23
|
+
import { t as requireApiKey } from "./required-api-key-D4kn3252.mjs";
|
|
23
24
|
import { n as resolveOpenAICodexAccountId } from "./openai-chatgpt-jwt-KWcgd0d_.mjs";
|
|
24
25
|
//#region packages/ai/src/providers/openai-chatgpt-responses-events.ts
|
|
25
26
|
var CodexApiError = class extends Error {
|
|
@@ -138,6 +139,142 @@ async function* parseOpenAIChatGptResponsesSse(response) {
|
|
|
138
139
|
} catch {}
|
|
139
140
|
}
|
|
140
141
|
}
|
|
142
|
+
const DEFAULT_CODEX_BASE_URL = "https://chatgpt.com/backend-api";
|
|
143
|
+
function resolveCodexUrl(baseUrl) {
|
|
144
|
+
const normalized = (baseUrl && baseUrl.trim().length > 0 ? baseUrl : DEFAULT_CODEX_BASE_URL).replace(/\/+$/, "");
|
|
145
|
+
if (normalized.endsWith("/codex/responses")) return normalized;
|
|
146
|
+
if (normalized.endsWith("/codex")) return `${normalized}/responses`;
|
|
147
|
+
return `${normalized}/codex/responses`;
|
|
148
|
+
}
|
|
149
|
+
function resolveCodexWebSocketUrl(baseUrl) {
|
|
150
|
+
const url = new URL(resolveCodexUrl(baseUrl));
|
|
151
|
+
if (url.protocol === "https:") url.protocol = "wss:";
|
|
152
|
+
if (url.protocol === "http:") url.protocol = "ws:";
|
|
153
|
+
return url.toString();
|
|
154
|
+
}
|
|
155
|
+
//#endregion
|
|
156
|
+
//#region packages/ai/src/providers/openai-chatgpt-responses-websocket-authority.ts
|
|
157
|
+
const OPENAI_BETA_RESPONSES_WEBSOCKETS = "responses_websockets=2026-02-06";
|
|
158
|
+
function createCodexWebSocketAuthority(transportHost, baseUrl, headers) {
|
|
159
|
+
return {
|
|
160
|
+
transportHost,
|
|
161
|
+
url: resolveCodexWebSocketUrl(baseUrl),
|
|
162
|
+
headers,
|
|
163
|
+
normalizedHeaders: Array.from(headers.entries()).filter(([name]) => name !== "traceparent")
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
function resolveCodexWebSocketAuthority(params) {
|
|
167
|
+
return params.transport === "sse" ? void 0 : createCodexWebSocketAuthority(params.transportHost, params.baseUrl, params.headers());
|
|
168
|
+
}
|
|
169
|
+
function buildCodexWebSocketHeaders(baseHeaders, requestId) {
|
|
170
|
+
baseHeaders.delete("accept");
|
|
171
|
+
baseHeaders.delete("content-type");
|
|
172
|
+
baseHeaders.delete("OpenAI-Beta");
|
|
173
|
+
baseHeaders.delete("openai-beta");
|
|
174
|
+
baseHeaders.set("OpenAI-Beta", OPENAI_BETA_RESPONSES_WEBSOCKETS);
|
|
175
|
+
baseHeaders.set("x-client-request-id", requestId);
|
|
176
|
+
baseHeaders.set("session_id", requestId);
|
|
177
|
+
return baseHeaders;
|
|
178
|
+
}
|
|
179
|
+
function matchesCodexWebSocketAuthority(cached, requested) {
|
|
180
|
+
return cached.transportHost === requested.transportHost && cached.url === requested.url && cached.normalizedHeaders.length === requested.normalizedHeaders.length && cached.normalizedHeaders.every(([name, value], index) => name === requested.normalizedHeaders[index]?.[0] && value === requested.normalizedHeaders[index]?.[1]);
|
|
181
|
+
}
|
|
182
|
+
const MAX_SSE_FALLBACK_AUTHORITIES_PER_SESSION = 8;
|
|
183
|
+
function hasCodexWebSocketSseFallback(fallbacksBySession, sessionId, authority) {
|
|
184
|
+
return Boolean(sessionId && fallbacksBySession.get(sessionId)?.some((fallback) => matchesCodexWebSocketAuthority(fallback, authority)));
|
|
185
|
+
}
|
|
186
|
+
function addCodexWebSocketSseFallback(fallbacksBySession, sessionId, authority) {
|
|
187
|
+
const fallbacks = fallbacksBySession.get(sessionId) ?? [];
|
|
188
|
+
if (fallbacks.some((fallback) => matchesCodexWebSocketAuthority(fallback, authority))) return;
|
|
189
|
+
if (fallbacks.length === MAX_SSE_FALLBACK_AUTHORITIES_PER_SESSION) fallbacks.shift();
|
|
190
|
+
fallbacks.push(authority);
|
|
191
|
+
if (!fallbacksBySession.has(sessionId)) fallbacksBySession.set(sessionId, fallbacks);
|
|
192
|
+
}
|
|
193
|
+
function clearCodexWebSocketSseFallback(fallbacksBySession, sessionId) {
|
|
194
|
+
if (sessionId) {
|
|
195
|
+
fallbacksBySession.delete(sessionId);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
fallbacksBySession.clear();
|
|
199
|
+
}
|
|
200
|
+
//#endregion
|
|
201
|
+
//#region packages/ai/src/providers/openai-chatgpt-responses-websocket-state.ts
|
|
202
|
+
const SESSION_WEBSOCKET_CACHE_TTL_MS = 3e5;
|
|
203
|
+
const SESSION_WEBSOCKET_MAX_AGE_MS = 33e5;
|
|
204
|
+
const runtimeStates = /* @__PURE__ */ new WeakMap();
|
|
205
|
+
const runtimeStateReferences = /* @__PURE__ */ new Set();
|
|
206
|
+
const runtimeStateFinalizer = new FinalizationRegistry((reference) => runtimeStateReferences.delete(reference));
|
|
207
|
+
function getOpenAICodexWebSocketRuntimeState(transportHost) {
|
|
208
|
+
let state = runtimeStates.get(transportHost);
|
|
209
|
+
if (!state) {
|
|
210
|
+
state = {
|
|
211
|
+
sessionCache: /* @__PURE__ */ new Map(),
|
|
212
|
+
sseFallbacks: /* @__PURE__ */ new Map()
|
|
213
|
+
};
|
|
214
|
+
runtimeStates.set(transportHost, state);
|
|
215
|
+
const reference = new WeakRef(state);
|
|
216
|
+
runtimeStateReferences.add(reference);
|
|
217
|
+
runtimeStateFinalizer.register(state, reference, reference);
|
|
218
|
+
}
|
|
219
|
+
return state;
|
|
220
|
+
}
|
|
221
|
+
function closeWebSocketSilently(socket, code = 1e3, reason = "done") {
|
|
222
|
+
try {
|
|
223
|
+
socket.close(code, reason);
|
|
224
|
+
} catch {}
|
|
225
|
+
}
|
|
226
|
+
function isWebSocketReusable(socket) {
|
|
227
|
+
return socket.readyState === void 0 || socket.readyState === 1;
|
|
228
|
+
}
|
|
229
|
+
function isWebSocketSessionExpired(entry) {
|
|
230
|
+
return Date.now() - entry.createdAt >= SESSION_WEBSOCKET_MAX_AGE_MS;
|
|
231
|
+
}
|
|
232
|
+
function deleteOwnedWebSocketSession(state, sessionId, entry) {
|
|
233
|
+
if (state.sessionCache.get(sessionId) === entry) state.sessionCache.delete(sessionId);
|
|
234
|
+
}
|
|
235
|
+
function setOwnedWebSocketSession(state, sessionId, entry, expected) {
|
|
236
|
+
if (state.sessionCache.get(sessionId) !== expected) return false;
|
|
237
|
+
state.sessionCache.set(sessionId, entry);
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
function scheduleSessionWebSocketExpiry(state, sessionId, entry) {
|
|
241
|
+
if (entry.idleTimer) clearTimeout(entry.idleTimer);
|
|
242
|
+
entry.idleTimer = setTimeout(() => {
|
|
243
|
+
if (entry.busy) return;
|
|
244
|
+
closeWebSocketSilently(entry.socket, 1e3, "idle_timeout");
|
|
245
|
+
deleteOwnedWebSocketSession(state, sessionId, entry);
|
|
246
|
+
}, SESSION_WEBSOCKET_CACHE_TTL_MS);
|
|
247
|
+
}
|
|
248
|
+
function closeRuntimeState(state, sessionId) {
|
|
249
|
+
const closeEntry = (entry) => {
|
|
250
|
+
if (entry.idleTimer) clearTimeout(entry.idleTimer);
|
|
251
|
+
closeWebSocketSilently(entry.socket, 1e3, "debug_close");
|
|
252
|
+
};
|
|
253
|
+
if (sessionId) {
|
|
254
|
+
clearCodexWebSocketSseFallback(state.sseFallbacks, sessionId);
|
|
255
|
+
const entry = state.sessionCache.get(sessionId);
|
|
256
|
+
if (entry) closeEntry(entry);
|
|
257
|
+
state.sessionCache.delete(sessionId);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
for (const entry of state.sessionCache.values()) closeEntry(entry);
|
|
261
|
+
state.sessionCache.clear();
|
|
262
|
+
clearCodexWebSocketSseFallback(state.sseFallbacks);
|
|
263
|
+
}
|
|
264
|
+
function closeOpenAICodexWebSocketState(transportHost, sessionId) {
|
|
265
|
+
const state = runtimeStates.get(transportHost);
|
|
266
|
+
if (state) closeRuntimeState(state, sessionId);
|
|
267
|
+
}
|
|
268
|
+
function closeAllOpenAICodexWebSocketStates(sessionId) {
|
|
269
|
+
for (const reference of runtimeStateReferences) {
|
|
270
|
+
const state = reference.deref();
|
|
271
|
+
if (!state) {
|
|
272
|
+
runtimeStateReferences.delete(reference);
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
closeRuntimeState(state, sessionId);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
141
278
|
//#endregion
|
|
142
279
|
//#region packages/ai/src/providers/openai-chatgpt-responses.ts
|
|
143
280
|
const dynamicImport = (specifier) => import(specifier);
|
|
@@ -146,7 +283,6 @@ function loadNodeOs() {
|
|
|
146
283
|
return process.getBuiltinModule?.("node:os") ?? null;
|
|
147
284
|
}
|
|
148
285
|
const os = loadNodeOs();
|
|
149
|
-
const DEFAULT_CODEX_BASE_URL = "https://chatgpt.com/backend-api";
|
|
150
286
|
const REQUEST_COMPRESSION_ZSTD_LEVEL = 3;
|
|
151
287
|
const CODEX_TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set(["openai", "opencode"]);
|
|
152
288
|
const WEBSOCKET_TRANSPORT_ERROR_CODE = "ERR_WEBSOCKET_TRANSPORT";
|
|
@@ -163,10 +299,6 @@ const RETRYABLE_WEBSOCKET_CLOSE_CODES = /* @__PURE__ */ new Set([
|
|
|
163
299
|
const WEBSOCKET_MESSAGE_TOO_BIG_CLOSE_CODE = 1009;
|
|
164
300
|
const WEBSOCKET_CONNECTION_LIMIT_REACHED_CODE = "websocket_connection_limit_reached";
|
|
165
301
|
const OPENAI_CHATGPT_RESPONSES_ERROR_BODY_MAX_BYTES = 16384;
|
|
166
|
-
function resolveRequestTimeoutMs(options) {
|
|
167
|
-
const timeoutMs = options?.timeoutMs;
|
|
168
|
-
return typeof timeoutMs === "number" && Number.isFinite(timeoutMs) && timeoutMs > 0 ? resolveTimerTimeoutMs(timeoutMs, 1) : void 0;
|
|
169
|
-
}
|
|
170
302
|
function buildRequestSignal(baseSignal, timeoutMs) {
|
|
171
303
|
if (timeoutMs === void 0) return baseSignal;
|
|
172
304
|
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
@@ -208,9 +340,10 @@ const streamOpenAICodexResponses = (model, context, options) => {
|
|
|
208
340
|
let firstEventAbort;
|
|
209
341
|
const output = createAssistantOutput(model);
|
|
210
342
|
try {
|
|
211
|
-
const unresolvedApiKey =
|
|
212
|
-
|
|
213
|
-
const
|
|
343
|
+
const unresolvedApiKey = requireApiKey(model.provider, options?.apiKey);
|
|
344
|
+
const transportHost = getAiTransportHost();
|
|
345
|
+
const websocketState = getOpenAICodexWebSocketRuntimeState(transportHost);
|
|
346
|
+
const apiKey = transportHost.resolveSecretSentinel(unresolvedApiKey);
|
|
214
347
|
const modelHeaders = resolveAiTransportHeaderSentinels(model.headers);
|
|
215
348
|
const optionHeaders = resolveAiTransportHeaderSentinels(options?.headers);
|
|
216
349
|
const accountId = extractOpenAICodexAccountId(apiKey);
|
|
@@ -227,7 +360,7 @@ const streamOpenAICodexResponses = (model, context, options) => {
|
|
|
227
360
|
const commitSemanticAttempt = (attempt) => commitResponsesEncryptedContentAttempt(attempt, (checkpoint) => suppressOpenAIResponsesCompaction(output, model, options, checkpoint));
|
|
228
361
|
const observePromptEgress = createResponsesPromptEgressObserver(options, context.systemPrompt);
|
|
229
362
|
const sessionId = clampOpenAIPromptCacheKey(options?.sessionId);
|
|
230
|
-
requestTimeoutMs =
|
|
363
|
+
requestTimeoutMs = clampPositiveTimerTimeoutMs(options?.timeoutMs);
|
|
231
364
|
requestTimeoutSignal = buildRequestSignal(options?.signal, requestTimeoutMs);
|
|
232
365
|
firstEventAbort = createFirstStreamEventAbortController(requestTimeoutSignal);
|
|
233
366
|
activeSignal = firstEventAbort.signal;
|
|
@@ -236,9 +369,25 @@ const streamOpenAICodexResponses = (model, context, options) => {
|
|
|
236
369
|
signal: activeSignal
|
|
237
370
|
};
|
|
238
371
|
const transport = options?.transport || "auto";
|
|
239
|
-
|
|
240
|
-
if (
|
|
241
|
-
|
|
372
|
+
let websocketAuthority;
|
|
373
|
+
if (!transportHost.requiresManagedTransport(model)) try {
|
|
374
|
+
websocketAuthority = resolveCodexWebSocketAuthority({
|
|
375
|
+
transport,
|
|
376
|
+
transportHost,
|
|
377
|
+
baseUrl: model.baseUrl,
|
|
378
|
+
headers: () => buildCodexWebSocketHeaders(buildBaseCodexHeaders(modelHeaders, optionHeaders, accountId, apiKey), sessionId || createCodexRequestId())
|
|
379
|
+
});
|
|
380
|
+
} catch (error) {
|
|
381
|
+
if (transport !== "auto") throw error;
|
|
382
|
+
appendAssistantMessageDiagnostic(output, createAssistantMessageDiagnostic("provider_transport_failure", error, {
|
|
383
|
+
configuredTransport: transport,
|
|
384
|
+
fallbackTransport: "sse",
|
|
385
|
+
eventsEmitted: false,
|
|
386
|
+
phase: "before_message_stream_start"
|
|
387
|
+
}));
|
|
388
|
+
}
|
|
389
|
+
const websocketDisabledForSession = transport === "auto" && websocketAuthority !== void 0 && hasCodexWebSocketSseFallback(websocketState.sseFallbacks, options?.sessionId, websocketAuthority);
|
|
390
|
+
if (websocketAuthority && !websocketDisabledForSession) {
|
|
242
391
|
let websocketStarted = false;
|
|
243
392
|
let websocketRequestSent = false;
|
|
244
393
|
let retriedWebSocketConnectionLimit = false;
|
|
@@ -247,7 +396,7 @@ const streamOpenAICodexResponses = (model, context, options) => {
|
|
|
247
396
|
websocketStarted = false;
|
|
248
397
|
websocketRequestSent = false;
|
|
249
398
|
try {
|
|
250
|
-
const terminal = await processWebSocketStream(
|
|
399
|
+
const terminal = await processWebSocketStream(websocketState, websocketAuthority, activeAttempt.request, output, stream, model, () => {
|
|
251
400
|
websocketStarted = true;
|
|
252
401
|
}, () => {
|
|
253
402
|
commitSemanticAttempt(activeAttempt);
|
|
@@ -285,7 +434,7 @@ const streamOpenAICodexResponses = (model, context, options) => {
|
|
|
285
434
|
phase: websocketStarted ? "after_message_stream_start" : "before_message_stream_start",
|
|
286
435
|
requestBytes: new TextEncoder().encode(JSON.stringify(activeAttempt.request)).byteLength
|
|
287
436
|
}));
|
|
288
|
-
if (transport === "auto" && options?.sessionId)
|
|
437
|
+
if (transport === "auto" && options?.sessionId) addCodexWebSocketSseFallback(websocketState.sseFallbacks, options.sessionId, websocketAuthority);
|
|
289
438
|
if (websocketStarted || transport !== "auto") throw error;
|
|
290
439
|
break;
|
|
291
440
|
}
|
|
@@ -313,7 +462,7 @@ const streamOpenAICodexResponses = (model, context, options) => {
|
|
|
313
462
|
activeSignal?.throwIfAborted();
|
|
314
463
|
lifecycle.assertCurrent();
|
|
315
464
|
}
|
|
316
|
-
attemptResponse = await fetch(resolveCodexUrl(model.baseUrl), {
|
|
465
|
+
attemptResponse = await (buildManagedModelFetch(model, transportHost) ?? fetch)(resolveCodexUrl(model.baseUrl), {
|
|
317
466
|
method: "POST",
|
|
318
467
|
headers: sseHeaders,
|
|
319
468
|
body: sseBody,
|
|
@@ -424,8 +573,7 @@ const streamOpenAICodexResponses = (model, context, options) => {
|
|
|
424
573
|
return stream;
|
|
425
574
|
};
|
|
426
575
|
const streamSimpleOpenAICodexResponses = (model, context, options) => {
|
|
427
|
-
const apiKey =
|
|
428
|
-
if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
|
|
576
|
+
const apiKey = requireApiKey(model.provider, options?.apiKey);
|
|
429
577
|
const resolvedOptions = {
|
|
430
578
|
...buildBaseOptions(model, options, apiKey),
|
|
431
579
|
authProfileId: options?.authProfileId,
|
|
@@ -479,18 +627,6 @@ function resolveCodexServiceTier(responseServiceTier, requestServiceTier) {
|
|
|
479
627
|
if (responseServiceTier === "default" && (requestServiceTier === "flex" || requestServiceTier === "priority")) return requestServiceTier;
|
|
480
628
|
return responseServiceTier ?? requestServiceTier;
|
|
481
629
|
}
|
|
482
|
-
function resolveCodexUrl(baseUrl) {
|
|
483
|
-
const normalized = (baseUrl && baseUrl.trim().length > 0 ? baseUrl : DEFAULT_CODEX_BASE_URL).replace(/\/+$/, "");
|
|
484
|
-
if (normalized.endsWith("/codex/responses")) return normalized;
|
|
485
|
-
if (normalized.endsWith("/codex")) return `${normalized}/responses`;
|
|
486
|
-
return `${normalized}/codex/responses`;
|
|
487
|
-
}
|
|
488
|
-
function resolveCodexWebSocketUrl(baseUrl) {
|
|
489
|
-
const url = new URL(resolveCodexUrl(baseUrl));
|
|
490
|
-
if (url.protocol === "https:") url.protocol = "wss:";
|
|
491
|
-
if (url.protocol === "http:") url.protocol = "ws:";
|
|
492
|
-
return url.toString();
|
|
493
|
-
}
|
|
494
630
|
/**
|
|
495
631
|
* Structured refusal code carried by the OpenAI Responses transport. Every
|
|
496
632
|
* terminal Responses path preserves it: a non-OK HTTP body parsed by
|
|
@@ -521,36 +657,18 @@ function isCodexNonTransportError(error) {
|
|
|
521
657
|
function isWebSocketConnectionLimitReachedError(error) {
|
|
522
658
|
return error instanceof CodexApiError && error.code === WEBSOCKET_CONNECTION_LIMIT_REACHED_CODE;
|
|
523
659
|
}
|
|
524
|
-
const OPENAI_BETA_RESPONSES_WEBSOCKETS = "responses_websockets=2026-02-06";
|
|
525
|
-
const SESSION_WEBSOCKET_CACHE_TTL_MS = 3e5;
|
|
526
|
-
const SESSION_WEBSOCKET_MAX_AGE_MS = 33e5;
|
|
527
|
-
const websocketSessionCache = /* @__PURE__ */ new Map();
|
|
528
|
-
const websocketSseFallbackSessions = /* @__PURE__ */ new Set();
|
|
529
660
|
let cachedWebsocket = null;
|
|
530
661
|
function resetOpenAICodexWebSocketStateForTest() {
|
|
531
662
|
cachedWebsocket = null;
|
|
532
|
-
websocketSseFallbackSessions.clear();
|
|
533
663
|
}
|
|
534
|
-
function closeOpenAICodexWebSocketSessions(sessionId) {
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
closeWebSocketSilently(entry.socket, 1e3, "debug_close");
|
|
538
|
-
};
|
|
539
|
-
if (sessionId) {
|
|
540
|
-
websocketSseFallbackSessions.delete(sessionId);
|
|
541
|
-
const entry = websocketSessionCache.get(sessionId);
|
|
542
|
-
if (entry) closeEntry(entry);
|
|
543
|
-
websocketSessionCache.delete(sessionId);
|
|
664
|
+
function closeOpenAICodexWebSocketSessions(sessionId, owner) {
|
|
665
|
+
if (owner) {
|
|
666
|
+
closeOpenAICodexWebSocketState(owner, sessionId);
|
|
544
667
|
return;
|
|
545
668
|
}
|
|
546
|
-
|
|
547
|
-
websocketSessionCache.clear();
|
|
548
|
-
websocketSseFallbackSessions.clear();
|
|
669
|
+
closeAllOpenAICodexWebSocketStates(sessionId);
|
|
549
670
|
}
|
|
550
671
|
registerSessionResourceCleanup(closeOpenAICodexWebSocketSessions);
|
|
551
|
-
function isWebSocketSseFallbackActive(sessionId) {
|
|
552
|
-
return sessionId ? websocketSseFallbackSessions.has(sessionId) : false;
|
|
553
|
-
}
|
|
554
672
|
async function getWebSocketConstructor() {
|
|
555
673
|
if (cachedWebsocket) return cachedWebsocket;
|
|
556
674
|
if (process?.versions?.bun && (process.env.HTTP_PROXY || process.env.HTTPS_PROXY || process.env.http_proxy || process.env.https_proxy)) {
|
|
@@ -576,40 +694,6 @@ async function getWebSocketConstructor() {
|
|
|
576
694
|
function createWebSocketTransportError(message, cause) {
|
|
577
695
|
return Object.assign(new Error(message, cause ? { cause } : void 0), { code: extractErrorCodeOrErrno(cause) ?? WEBSOCKET_TRANSPORT_ERROR_CODE });
|
|
578
696
|
}
|
|
579
|
-
function getWebSocketReadyState(socket) {
|
|
580
|
-
const readyState = socket.readyState;
|
|
581
|
-
return typeof readyState === "number" ? readyState : void 0;
|
|
582
|
-
}
|
|
583
|
-
function isWebSocketReusable(socket) {
|
|
584
|
-
const readyState = getWebSocketReadyState(socket);
|
|
585
|
-
return readyState === void 0 || readyState === 1;
|
|
586
|
-
}
|
|
587
|
-
function isWebSocketSessionExpired(entry) {
|
|
588
|
-
return Date.now() - entry.createdAt >= SESSION_WEBSOCKET_MAX_AGE_MS;
|
|
589
|
-
}
|
|
590
|
-
function closeWebSocketSilently(socket, code = 1e3, reason = "done") {
|
|
591
|
-
try {
|
|
592
|
-
socket.close(code, reason);
|
|
593
|
-
} catch {}
|
|
594
|
-
}
|
|
595
|
-
function deleteOwnedWebSocketSession(sessionId, entry) {
|
|
596
|
-
if (websocketSessionCache.get(sessionId) === entry) websocketSessionCache.delete(sessionId);
|
|
597
|
-
}
|
|
598
|
-
function setOwnedWebSocketSession(sessionId, entry, expected) {
|
|
599
|
-
if (websocketSessionCache.get(sessionId) === expected) {
|
|
600
|
-
websocketSessionCache.set(sessionId, entry);
|
|
601
|
-
return true;
|
|
602
|
-
}
|
|
603
|
-
return false;
|
|
604
|
-
}
|
|
605
|
-
function scheduleSessionWebSocketExpiry(sessionId, entry) {
|
|
606
|
-
if (entry.idleTimer) clearTimeout(entry.idleTimer);
|
|
607
|
-
entry.idleTimer = setTimeout(() => {
|
|
608
|
-
if (entry.busy) return;
|
|
609
|
-
closeWebSocketSilently(entry.socket, 1e3, "idle_timeout");
|
|
610
|
-
deleteOwnedWebSocketSession(sessionId, entry);
|
|
611
|
-
}, SESSION_WEBSOCKET_CACHE_TTL_MS);
|
|
612
|
-
}
|
|
613
697
|
async function connectWebSocket(url, headers, signal) {
|
|
614
698
|
const WebSocketCtor = await getWebSocketConstructor();
|
|
615
699
|
if (!WebSocketCtor) throw new Error("WebSocket transport is not available in this runtime");
|
|
@@ -667,79 +751,57 @@ async function connectWebSocket(url, headers, signal) {
|
|
|
667
751
|
signal?.addEventListener("abort", onAbort);
|
|
668
752
|
});
|
|
669
753
|
}
|
|
670
|
-
async function acquireWebSocket(
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
754
|
+
async function acquireWebSocket(state, authority, sessionId, signal) {
|
|
755
|
+
const { url, headers } = authority;
|
|
756
|
+
const lease = (socket, entry) => ({
|
|
757
|
+
socket,
|
|
758
|
+
entry,
|
|
759
|
+
release: ({ keep } = {}) => {
|
|
760
|
+
if (!sessionId || !entry || !keep || !isWebSocketReusable(socket)) {
|
|
676
761
|
closeWebSocketSilently(socket);
|
|
762
|
+
if (entry?.idleTimer) clearTimeout(entry.idleTimer);
|
|
763
|
+
if (sessionId && entry) deleteOwnedWebSocketSession(state, sessionId, entry);
|
|
764
|
+
return;
|
|
677
765
|
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
766
|
+
entry.busy = false;
|
|
767
|
+
scheduleSessionWebSocketExpiry(state, sessionId, entry);
|
|
768
|
+
}
|
|
769
|
+
});
|
|
770
|
+
if (!sessionId) return lease(await connectWebSocket(url, headers, signal));
|
|
771
|
+
const cached = state.sessionCache.get(sessionId);
|
|
681
772
|
let expectedCacheValue = cached;
|
|
682
773
|
if (cached) {
|
|
683
774
|
if (cached.idleTimer) {
|
|
684
775
|
clearTimeout(cached.idleTimer);
|
|
685
776
|
cached.idleTimer = void 0;
|
|
686
777
|
}
|
|
687
|
-
if (!cached.busy &&
|
|
778
|
+
if (!cached.busy && !matchesCodexWebSocketAuthority(cached.authority, authority)) {
|
|
779
|
+
closeWebSocketSilently(cached.socket, 1e3, "authority_changed");
|
|
780
|
+
deleteOwnedWebSocketSession(state, sessionId, cached);
|
|
781
|
+
expectedCacheValue = void 0;
|
|
782
|
+
} else if (!cached.busy && isWebSocketSessionExpired(cached)) {
|
|
688
783
|
closeWebSocketSilently(cached.socket, 1e3, "connection_age_limit");
|
|
689
|
-
deleteOwnedWebSocketSession(sessionId, cached);
|
|
784
|
+
deleteOwnedWebSocketSession(state, sessionId, cached);
|
|
690
785
|
expectedCacheValue = void 0;
|
|
691
786
|
} else if (!cached.busy && isWebSocketReusable(cached.socket)) {
|
|
692
787
|
cached.busy = true;
|
|
693
|
-
return
|
|
694
|
-
socket: cached.socket,
|
|
695
|
-
entry: cached,
|
|
696
|
-
release: ({ keep } = {}) => {
|
|
697
|
-
if (!keep || !isWebSocketReusable(cached.socket)) {
|
|
698
|
-
closeWebSocketSilently(cached.socket);
|
|
699
|
-
deleteOwnedWebSocketSession(sessionId, cached);
|
|
700
|
-
return;
|
|
701
|
-
}
|
|
702
|
-
cached.busy = false;
|
|
703
|
-
scheduleSessionWebSocketExpiry(sessionId, cached);
|
|
704
|
-
}
|
|
705
|
-
};
|
|
706
|
-
}
|
|
707
|
-
if (cached.busy) {
|
|
708
|
-
const socket = await connectWebSocket(url, headers, signal);
|
|
709
|
-
return {
|
|
710
|
-
socket,
|
|
711
|
-
release: () => {
|
|
712
|
-
closeWebSocketSilently(socket);
|
|
713
|
-
}
|
|
714
|
-
};
|
|
788
|
+
return lease(cached.socket, cached);
|
|
715
789
|
}
|
|
790
|
+
if (cached.busy) return lease(await connectWebSocket(url, headers, signal));
|
|
716
791
|
if (!isWebSocketReusable(cached.socket)) {
|
|
717
792
|
closeWebSocketSilently(cached.socket);
|
|
718
|
-
deleteOwnedWebSocketSession(sessionId, cached);
|
|
793
|
+
deleteOwnedWebSocketSession(state, sessionId, cached);
|
|
719
794
|
expectedCacheValue = void 0;
|
|
720
795
|
}
|
|
721
796
|
}
|
|
722
797
|
const socket = await connectWebSocket(url, headers, signal);
|
|
723
798
|
const entry = {
|
|
724
799
|
socket,
|
|
800
|
+
authority,
|
|
725
801
|
busy: true,
|
|
726
802
|
createdAt: Date.now()
|
|
727
803
|
};
|
|
728
|
-
|
|
729
|
-
return {
|
|
730
|
-
socket,
|
|
731
|
-
entry: ownsCache ? entry : void 0,
|
|
732
|
-
release: ({ keep } = {}) => {
|
|
733
|
-
if (!ownsCache || !keep || !isWebSocketReusable(entry.socket)) {
|
|
734
|
-
closeWebSocketSilently(entry.socket);
|
|
735
|
-
if (entry.idleTimer) clearTimeout(entry.idleTimer);
|
|
736
|
-
deleteOwnedWebSocketSession(sessionId, entry);
|
|
737
|
-
return;
|
|
738
|
-
}
|
|
739
|
-
entry.busy = false;
|
|
740
|
-
scheduleSessionWebSocketExpiry(sessionId, entry);
|
|
741
|
-
}
|
|
742
|
-
};
|
|
804
|
+
return lease(socket, setOwnedWebSocketSession(state, sessionId, entry, expectedCacheValue) ? entry : void 0);
|
|
743
805
|
}
|
|
744
806
|
function extractWebSocketError(event) {
|
|
745
807
|
if (event && typeof event === "object") {
|
|
@@ -903,8 +965,8 @@ async function* startWebSocketOutputOnFirstEvent(events, output, stream, onFirst
|
|
|
903
965
|
yield event;
|
|
904
966
|
}
|
|
905
967
|
}
|
|
906
|
-
async function processWebSocketStream(
|
|
907
|
-
const { socket, entry, release } = await acquireWebSocket(
|
|
968
|
+
async function processWebSocketStream(state, authority, body, output, stream, model, onFirstProviderEvent, onStart, options, abortFirstEventStream, observePromptEgress, payloadVariant = "initial", onRequestSent, activitySignal) {
|
|
969
|
+
const { socket, entry, release } = await acquireWebSocket(state, authority, options?.sessionId, options?.signal);
|
|
908
970
|
let keepConnection = true;
|
|
909
971
|
const useCachedContext = options?.transport === "websocket-cached" || options?.transport === "auto";
|
|
910
972
|
const fullBody = body;
|
|
@@ -1080,16 +1142,5 @@ function buildSSEHeaders(initHeaders, additionalHeaders, accountId, token, sessi
|
|
|
1080
1142
|
}
|
|
1081
1143
|
return headers;
|
|
1082
1144
|
}
|
|
1083
|
-
function buildWebSocketHeaders(initHeaders, additionalHeaders, accountId, token, requestId) {
|
|
1084
|
-
const headers = buildBaseCodexHeaders(initHeaders, additionalHeaders, accountId, token);
|
|
1085
|
-
headers.delete("accept");
|
|
1086
|
-
headers.delete("content-type");
|
|
1087
|
-
headers.delete("OpenAI-Beta");
|
|
1088
|
-
headers.delete("openai-beta");
|
|
1089
|
-
headers.set("OpenAI-Beta", OPENAI_BETA_RESPONSES_WEBSOCKETS);
|
|
1090
|
-
headers.set("x-client-request-id", requestId);
|
|
1091
|
-
headers.set("session_id", requestId);
|
|
1092
|
-
return headers;
|
|
1093
|
-
}
|
|
1094
1145
|
//#endregion
|
|
1095
1146
|
export { closeOpenAICodexWebSocketSessions, extractOpenAICodexAccountId, resetOpenAICodexWebSocketStateForTest, streamOpenAICodexResponses, streamSimpleOpenAICodexResponses };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
|
|
2
|
+
import { k as clampThinkingLevel } from "./host-DCW52iHe.mjs";
|
|
3
|
+
import { n as buildBaseOptions } from "./simple-options-BkKTXxhp.mjs";
|
|
4
|
+
import { i as convertMessages, n as streamOpenAICompletionsRequest } from "./openai-completions-transport-DWM2mQDB.mjs";
|
|
5
|
+
import { t as requireApiKey } from "./required-api-key-D4kn3252.mjs";
|
|
6
|
+
//#region packages/ai/src/providers/openai-completions.ts
|
|
7
|
+
var openai_completions_exports = /* @__PURE__ */ __exportAll({
|
|
8
|
+
convertMessages: () => convertMessages,
|
|
9
|
+
streamOpenAICompletions: () => streamOpenAICompletions,
|
|
10
|
+
streamSimpleOpenAICompletions: () => streamSimpleOpenAICompletions
|
|
11
|
+
});
|
|
12
|
+
const streamOpenAICompletions = (model, context, options) => streamOpenAICompletionsRequest(model, context, options, "direct");
|
|
13
|
+
const streamSimpleOpenAICompletions = (model, context, options) => {
|
|
14
|
+
const apiKey = requireApiKey(model.provider, options?.apiKey);
|
|
15
|
+
const base = buildBaseOptions(model, options, apiKey);
|
|
16
|
+
const clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : void 0;
|
|
17
|
+
const toolChoice = options?.toolChoice;
|
|
18
|
+
return streamOpenAICompletions(model, context, {
|
|
19
|
+
...base,
|
|
20
|
+
reasoningEffort: clampedReasoning,
|
|
21
|
+
toolChoice
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
//#endregion
|
|
25
|
+
export { streamOpenAICompletions as n, streamSimpleOpenAICompletions as r, openai_completions_exports as t };
|
package/dist/{openai-completions-compat-qJjmqQ71.d.mts → openai-completions-compat-BYdYpXhU.d.mts}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "./index-
|
|
2
|
-
import {
|
|
3
|
-
import { a as AiProviderRequestPolicyInput, i as AiProviderRequestCapabilities } from "./host-
|
|
1
|
+
import "./index-a8e_oKnu.mjs";
|
|
2
|
+
import { N as OpenAICompletionsCompat, k as Model } from "./types-DvzmWW8J.mjs";
|
|
3
|
+
import { a as AiProviderRequestPolicyInput, i as AiProviderRequestCapabilities } from "./host-BinBeGcQ.mjs";
|
|
4
4
|
//#region packages/ai/src/transports/openai-completions-compat.d.ts
|
|
5
5
|
type ProviderRequestCapabilities = AiProviderRequestCapabilities;
|
|
6
6
|
type OpenAICompletionsSessionAffinity = "none" | "openai" | "openrouter";
|
package/dist/{openai-completions-compat-BOVWBZDn.mjs → openai-completions-compat-BdmlhD4u.mjs}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { o as isRecord } from "./record-coerce-CNDovvft.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { a as resolveProviderRequestCapabilities } from "./host-policy-B3jc4Rpn.mjs";
|
|
3
3
|
//#region packages/ai/src/providers/openai-response-format.ts
|
|
4
4
|
const JSON_SCHEMA_RESPONSE_FORMAT_NAME = "openclaw_response";
|
|
5
5
|
const OLLAMA_CLOUD_ORIGIN = "https://ollama.com";
|
|
@@ -16,11 +16,7 @@ function isKnownOpenAIJsonSchemaModelId(modelId) {
|
|
|
16
16
|
function shouldOmitOllamaCompatResponseFormat(params) {
|
|
17
17
|
if (!params.provider.includes("ollama")) return false;
|
|
18
18
|
if (params.hasTools()) return true;
|
|
19
|
-
|
|
20
|
-
return new URL(params.baseUrl).origin === OLLAMA_CLOUD_ORIGIN;
|
|
21
|
-
} catch {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
19
|
+
return URL.parse(params.baseUrl)?.origin === OLLAMA_CLOUD_ORIGIN;
|
|
24
20
|
}
|
|
25
21
|
/**
|
|
26
22
|
* Maps the shared JSON Schema option to Chat Completions while preserving the
|
|
@@ -38,6 +34,22 @@ function resolveOpenAICompletionsResponseFormat(responseFormat, supportsJsonSche
|
|
|
38
34
|
}
|
|
39
35
|
};
|
|
40
36
|
}
|
|
37
|
+
/** Maps shared or provider-shaped structured-output options to the Responses API text format. */
|
|
38
|
+
function resolveOpenAIResponsesTextFormat(responseFormat) {
|
|
39
|
+
if (responseFormat.type === "json_schema") return {
|
|
40
|
+
...isRecord(responseFormat.json_schema) ? responseFormat.json_schema : responseFormat,
|
|
41
|
+
type: "json_schema"
|
|
42
|
+
};
|
|
43
|
+
if (responseFormat.type === "json_object" || responseFormat.type === "text") return {
|
|
44
|
+
...responseFormat,
|
|
45
|
+
type: responseFormat.type
|
|
46
|
+
};
|
|
47
|
+
return {
|
|
48
|
+
type: "json_schema",
|
|
49
|
+
name: JSON_SCHEMA_RESPONSE_FORMAT_NAME,
|
|
50
|
+
schema: responseFormat
|
|
51
|
+
};
|
|
52
|
+
}
|
|
41
53
|
//#endregion
|
|
42
54
|
//#region packages/ai/src/transports/openai-completions-compat.ts
|
|
43
55
|
function isDefaultRouteProvider(provider, ...ids) {
|
|
@@ -55,22 +67,17 @@ function isOpenAICodexResponsesModel(model) {
|
|
|
55
67
|
}
|
|
56
68
|
function isNativeOpenAICodexResponsesBaseUrl(baseUrl) {
|
|
57
69
|
const trimmed = typeof baseUrl === "string" ? baseUrl.trim() : "";
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"/backend-api/codex/responses"
|
|
70
|
-
].includes(pathname);
|
|
71
|
-
} catch {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
70
|
+
const url = URL.parse(trimmed);
|
|
71
|
+
if (!url || url.protocol !== "http:" && url.protocol !== "https:") return false;
|
|
72
|
+
if (url.hostname.toLowerCase() !== "chatgpt.com") return false;
|
|
73
|
+
const pathname = url.pathname.replace(/\/+$/u, "").toLowerCase();
|
|
74
|
+
return [
|
|
75
|
+
"/backend-api",
|
|
76
|
+
"/backend-api/v1",
|
|
77
|
+
"/backend-api/codex",
|
|
78
|
+
"/backend-api/codex/v1",
|
|
79
|
+
"/backend-api/codex/responses"
|
|
80
|
+
].includes(pathname);
|
|
74
81
|
}
|
|
75
82
|
function usesNativeOpenAICodexResponsesBackend(model) {
|
|
76
83
|
return isOpenAICodexResponsesModel(model) && isNativeOpenAICodexResponsesBaseUrl(model.baseUrl);
|
|
@@ -170,4 +177,4 @@ function resolveOpenAICompletionsCompat(model, resolveCapabilities) {
|
|
|
170
177
|
};
|
|
171
178
|
}
|
|
172
179
|
//#endregion
|
|
173
|
-
export { resolveOpenAIPromptCacheKeySupport as a,
|
|
180
|
+
export { resolveOpenAIPromptCacheKeySupport as a, resolveOpenAIResponsesTextFormat as c, resolveOpenAICompletionsCompat as i, shouldOmitOllamaCompatResponseFormat as l, isNativeOpenAIEndpoint as n, usesNativeOpenAICodexResponsesBackend as o, isOpenAICodexResponsesModel as r, resolveOpenAICompletionsResponseFormat as s, detectOpenAICompletionsCompat as t };
|