@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-completions-stream-CDCuw3DP.mjs → openai-completions-transport-DWM2mQDB.mjs}
RENAMED
|
@@ -1,28 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as runtimeContextContentToText, f as hasRuntimeContextMarker, p as isRuntimeContextMessage } from "./types-CQc6JNG4.mjs";
|
|
2
|
+
import { r as appendAssistantThinking } from "./event-stream-C5AbCAaZ.mjs";
|
|
2
3
|
import { o as isRecord } from "./record-coerce-CNDovvft.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import { n as
|
|
5
|
-
import { r as
|
|
6
|
-
import {
|
|
7
|
-
import { r as
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { c as
|
|
12
|
-
import {
|
|
13
|
-
import { t as
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { C as
|
|
17
|
-
import { a as
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import { a as
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
4
|
+
import { s as readNonEmptyStringPreservingWhitespace, t as hasNonEmptyString } from "./string-coerce-CtgOVOSv.mjs";
|
|
5
|
+
import { n as asNonNegativeFiniteNumber } from "./number-coercion-V8-BhME4.mjs";
|
|
6
|
+
import { N as isImageWithMediaPayload, r as getAiTransportHost } from "./host-DCW52iHe.mjs";
|
|
7
|
+
import { _ as isOpenAIGpt54MiniModel, v as isOpenAIGpt55Model, y as isOpenAIGpt56Model } from "./openai-responses-contracts-BKu8O7l4.mjs";
|
|
8
|
+
import { r as uniqueStrings } from "./string-normalization-PN10hf6d.mjs";
|
|
9
|
+
import { o as truncateUtf16Safe } from "./provider-error-DQBE1bUQ.mjs";
|
|
10
|
+
import { r as resolveOpenAIPromptCacheParams } from "./openai-prompt-cache-I8YQTzf8.mjs";
|
|
11
|
+
import { r as emitModelTransportDebug } from "./diagnostics-Caj-4RBA.mjs";
|
|
12
|
+
import { c as supportsModelTools, r as estimateStringChars } from "./text-signature-MLwfi6fq.mjs";
|
|
13
|
+
import { i as resolveOpenAICompletionsCompat, l as shouldOmitOllamaCompatResponseFormat, n as isNativeOpenAIEndpoint, s as resolveOpenAICompletionsResponseFormat, t as detectOpenAICompletionsCompat } from "./openai-completions-compat-BdmlhD4u.mjs";
|
|
14
|
+
import { i as resolveProviderEndpoint, t as buildGuardedModelFetch } from "./host-policy-B3jc4Rpn.mjs";
|
|
15
|
+
import { i as resolveCacheRetention, r as buildCopilotDynamicHeaders } from "./cloudflare-5qSGvIUH.mjs";
|
|
16
|
+
import { E as createToolArgumentPreviewSchedule, O as parseStreamingJson, P as sanitizeSurrogates, S as withProviderResponseHook, _ as sanitizeNonEmptyTransportPayloadText, b as transportAbortError, c as failTransportStream, d as iterateModelStream, l as finalizeTerminalToolCallArguments, s as createWritableTransportEventStream, u as finalizeTransportStream, y as throwIfModelStreamAborted } from "./transport-stream-shared-CxXXz_Dd.mjs";
|
|
17
|
+
import { C as stripSystemPromptCacheBoundary, D as sortPromptCacheToolsByName, S as splitSystemPromptRelocatableBoundary, d as describeToolResultMediaPlaceholder, l as codeModeToolSurfaceObserver, m as extractToolResultText, s as prepareModelRequestBody, u as reasoningTagTextPolicy, w as stripSystemPromptRelocatableBoundary, x as splitSystemPromptCacheBoundary } from "./simple-options-BkKTXxhp.mjs";
|
|
18
|
+
import { C as log, D as readOpenAICompletionsReasoningBatch, E as readOpenAICompletionsContentDeltas, O as resolveOpenAIClientBaseUrl, S as isOpenAICompletionsThinkingEnabled, T as parseOpenAICompletionsUsage, a as enforceCodeModeResponsesToolSurface, d as prepareOpenAITools, f as projectOpenAITools, g as resolveOpenAISimpleReasoningEffort, h as resolveOpenAIRequestReasoning, i as buildOpenAISdkRequestOptions, k as resolvePromptCacheKey, l as resolveCodeModeResponsesVisibleToolNames, n as buildOpenAIClientHeaders, p as reconcileOpenAICompletionsToolChoice, r as buildOpenAISdkClientOptions, s as getCompat, t as assertCodeModeResponsesToolSurface, u as resolveOpenAIStrictToolFlagWithDiagnostics, v as GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, w as measureUtf8AppendBytes, y as createOpenAIProviderAcceptanceHook } from "./openai-transport-params-JFsnIyto.mjs";
|
|
19
|
+
import { n as getEnvApiKey } from "./env-api-keys-CyX4VKGO.mjs";
|
|
20
|
+
import { n as transformProviderMessages, t as createAssistantOutput } from "./assistant-output-OLm-Oln0.mjs";
|
|
21
|
+
import { a as tagUnresolvedTextAsCommentary, i as tagPendingCommentaryText, n as rememberPendingCommentaryTags, r as tagInterruptedTextPhases, t as clearPendingCommentaryText } from "./assistant-text-phase-Bl1aDCB7.mjs";
|
|
22
|
+
import { t as notifyLlmRequestActivity } from "./llm-request-activity-D8f_oxHj.mjs";
|
|
23
|
+
import { n as resolveOpencodeSessionHeaders } from "./session-affinity-DA4WHv1h.mjs";
|
|
24
|
+
import "./types.mjs";
|
|
25
|
+
import { i as createOpenAIProviderClient, n as resolveProviderSimpleCompletionHeaders, r as resolveProviderTransportTurnState, t as filterProviderTurnHeadersForExplicitOpencodeSession } from "./provider-transport-turn-state-_M2kLdUE.mjs";
|
|
26
|
+
import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-D9ZmL_s9.mjs";
|
|
27
|
+
import { f as withPreparedToolSchemaNormalization, r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-DYNePiF8.mjs";
|
|
28
|
+
import { isGoogleGemini3ThinkingLevelModel } from "./internal/google-model-family.mjs";
|
|
23
29
|
import { t as mapOpenAIStopReason } from "./openai-stop-reason-8s70vDXj.mjs";
|
|
24
|
-
import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-
|
|
30
|
+
import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-Ju9VpUGl.mjs";
|
|
25
31
|
import { randomUUID } from "node:crypto";
|
|
32
|
+
import OpenAI from "openai";
|
|
26
33
|
//#region packages/ai/src/transports/deepseek-dsml-grammar.ts
|
|
27
34
|
const DEEPSEEK_DSML_MARKERS = [
|
|
28
35
|
"|",
|
|
@@ -152,6 +159,34 @@ function canonicalizeMaxTokensParam(params) {
|
|
|
152
159
|
params.merged.maxTokens = resolved;
|
|
153
160
|
}
|
|
154
161
|
//#endregion
|
|
162
|
+
//#region packages/ai/src/transports/openai-compatible-conversation-turn.ts
|
|
163
|
+
function hasNonEmptyContentPart(part) {
|
|
164
|
+
if (!part || typeof part !== "object") return false;
|
|
165
|
+
const record = part;
|
|
166
|
+
if (record.type === "text") return hasNonEmptyString(record.text);
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
function hasNonEmptyMessageContent(content) {
|
|
170
|
+
if (hasNonEmptyString(content)) return true;
|
|
171
|
+
if (!Array.isArray(content)) return false;
|
|
172
|
+
return content.some(hasNonEmptyContentPart);
|
|
173
|
+
}
|
|
174
|
+
/** Returns whether an OpenAI-compatible messages payload contains a usable turn. */
|
|
175
|
+
function hasOpenAICompatibleConversationTurn(messages) {
|
|
176
|
+
if (!Array.isArray(messages)) return false;
|
|
177
|
+
return messages.some((message) => {
|
|
178
|
+
if (!message || typeof message !== "object") return false;
|
|
179
|
+
const record = message;
|
|
180
|
+
if (record.role === "user") return hasNonEmptyMessageContent(record.content);
|
|
181
|
+
if (record.role === "assistant") {
|
|
182
|
+
if (hasNonEmptyMessageContent(record.content)) return true;
|
|
183
|
+
const toolCalls = record.tool_calls;
|
|
184
|
+
return Array.isArray(toolCalls) && toolCalls.some((toolCall) => toolCall && typeof toolCall === "object");
|
|
185
|
+
}
|
|
186
|
+
return false;
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
//#endregion
|
|
155
190
|
//#region packages/ai/src/transports/openai-completions-cache-control.ts
|
|
156
191
|
const shapedPayloads = /* @__PURE__ */ new WeakSet();
|
|
157
192
|
function resolveCompletionsCacheControl(compat, retention, openRouterRoute) {
|
|
@@ -307,21 +342,16 @@ function createOpenAICompletionsToolCallDeltaNormalizer() {
|
|
|
307
342
|
pendingFollowingDeltaBytes += nextDeltaBytes;
|
|
308
343
|
pendingFollowingDeltas.push(delta);
|
|
309
344
|
};
|
|
310
|
-
const withoutToolCalls = (delta) => {
|
|
311
|
-
const ordinaryDelta = { ...delta };
|
|
312
|
-
delete ordinaryDelta.function_call;
|
|
313
|
-
delete ordinaryDelta.tool_calls;
|
|
314
|
-
return ordinaryDelta;
|
|
315
|
-
};
|
|
316
345
|
const hasObservableContent = (value) => {
|
|
317
346
|
if (typeof value === "string") return value.length > 0;
|
|
318
347
|
if (Array.isArray(value)) return value.some(hasObservableContent);
|
|
319
348
|
if (isRecord(value)) return Object.entries(value).some(([field, nestedValue]) => field !== "type" && field !== "id" && field !== "index" && hasObservableContent(nestedValue));
|
|
320
349
|
return false;
|
|
321
350
|
};
|
|
322
|
-
const hasOrdinaryContent = (delta) => Object.entries(delta).some(([field, value]) => field !== "role" && hasObservableContent(value));
|
|
323
351
|
return (delta, finishReason) => {
|
|
324
|
-
const ordinaryDelta =
|
|
352
|
+
const ordinaryDelta = { ...delta };
|
|
353
|
+
delete ordinaryDelta.function_call;
|
|
354
|
+
delete ordinaryDelta.tool_calls;
|
|
325
355
|
if (delta.tool_calls && delta.tool_calls.length > 0) {
|
|
326
356
|
for (const toolCall of delta.tool_calls) {
|
|
327
357
|
const index = typeof toolCall.index === "number" ? toolCall.index : void 0;
|
|
@@ -353,7 +383,7 @@ function createOpenAICompletionsToolCallDeltaNormalizer() {
|
|
|
353
383
|
}];
|
|
354
384
|
const hadPendingLegacyCall = pendingLegacyToolCall !== void 0;
|
|
355
385
|
const leadingDeltas = [];
|
|
356
|
-
if (
|
|
386
|
+
if (Object.entries(ordinaryDelta).some(([field, value]) => field !== "role" && hasObservableContent(value))) {
|
|
357
387
|
if (hadPendingLegacyCall) bufferFollowingDelta(ordinaryDelta);
|
|
358
388
|
else leadingDeltas.push({
|
|
359
389
|
delta: ordinaryDelta,
|
|
@@ -449,11 +479,6 @@ function isAzureOpenAICompatibleHost(hostname) {
|
|
|
449
479
|
}
|
|
450
480
|
//#endregion
|
|
451
481
|
//#region packages/ai/src/openai-completions-messages.ts
|
|
452
|
-
const EMPTY_TOOL_RESULT_TEXT = "(no output)";
|
|
453
|
-
function sanitizeToolResultText(text, fallback) {
|
|
454
|
-
const sanitized = sanitizeSurrogates(text);
|
|
455
|
-
return sanitized.trim().length > 0 ? sanitized : fallback;
|
|
456
|
-
}
|
|
457
482
|
/** Whether replayed messages require a tools marker for proxy compatibility. */
|
|
458
483
|
function hasToolCallHistory(messages) {
|
|
459
484
|
return messages.some((message) => message.role === "toolResult" || message.role === "assistant" && Array.isArray(message.content) && message.content.some((block) => block.type === "toolCall"));
|
|
@@ -492,7 +517,13 @@ function convertMessages(model, context, compat, options = {}) {
|
|
|
492
517
|
role: "assistant",
|
|
493
518
|
content: "I have processed the tool results."
|
|
494
519
|
});
|
|
495
|
-
if (msg
|
|
520
|
+
if (isRuntimeContextMessage(msg)) {
|
|
521
|
+
params.push({
|
|
522
|
+
role: model.reasoning && compat.supportsDeveloperRole ? "developer" : "system",
|
|
523
|
+
content: sanitizeSurrogates(runtimeContextContentToText(msg.content))
|
|
524
|
+
});
|
|
525
|
+
options.cacheOptOutIndexes?.add(params.length - 1);
|
|
526
|
+
} else if (msg.role === "user") {
|
|
496
527
|
let userParam;
|
|
497
528
|
if (typeof msg.content === "string") userParam = {
|
|
498
529
|
role: "user",
|
|
@@ -519,7 +550,7 @@ function convertMessages(model, context, compat, options = {}) {
|
|
|
519
550
|
content
|
|
520
551
|
};
|
|
521
552
|
}
|
|
522
|
-
if (msg
|
|
553
|
+
if (hasRuntimeContextMarker(msg)) options.cacheOptOutIndexes?.add(params.length);
|
|
523
554
|
params.push(userParam);
|
|
524
555
|
} else if (msg.role === "assistant") {
|
|
525
556
|
const assistantMsg = {
|
|
@@ -586,7 +617,7 @@ function convertMessages(model, context, compat, options = {}) {
|
|
|
586
617
|
const images = toolMsg.content.filter(isImageWithMediaPayload);
|
|
587
618
|
const toolResultMsg = {
|
|
588
619
|
role: "tool",
|
|
589
|
-
content:
|
|
620
|
+
content: sanitizeNonEmptyTransportPayloadText(textResult, mediaPlaceholder),
|
|
590
621
|
tool_call_id: toolMsg.toolCallId
|
|
591
622
|
};
|
|
592
623
|
if (compat.requiresToolResultName && toolMsg.toolName) toolResultMsg.name = toolMsg.toolName;
|
|
@@ -660,11 +691,9 @@ function applyDirectCompletionsReasoningAndRouting(params, model, reasoning, com
|
|
|
660
691
|
enable_thinking: reasoningEnabled,
|
|
661
692
|
preserve_thinking: true
|
|
662
693
|
};
|
|
663
|
-
else if (compat.thinkingFormat === "deepseek" && model.reasoning) {
|
|
664
|
-
params.thinking = { type: reasoningEnabled ? "enabled" : "disabled" };
|
|
665
|
-
|
|
666
|
-
} else if (compat.thinkingFormat === "together" && model.reasoning) {
|
|
667
|
-
params.reasoning = { enabled: reasoningEnabled };
|
|
694
|
+
else if ((compat.thinkingFormat === "deepseek" || compat.thinkingFormat === "together") && model.reasoning) {
|
|
695
|
+
if (compat.thinkingFormat === "deepseek") params.thinking = { type: reasoningEnabled ? "enabled" : "disabled" };
|
|
696
|
+
else params.reasoning = { enabled: reasoningEnabled };
|
|
668
697
|
if (reasoningEnabled && compat.supportsReasoningEffort && nativeEffort !== void 0) params.reasoning_effort = nativeEffort;
|
|
669
698
|
} else if (model.reasoning && compat.supportsReasoningEffort && nativeEffort !== void 0) params.reasoning_effort = nativeEffort;
|
|
670
699
|
if (compat.openRouterRouting) params.provider = compat.openRouterRouting;
|
|
@@ -684,9 +713,6 @@ function isGoogleOpenAICompatModel(model) {
|
|
|
684
713
|
const endpointClass = detectOpenAICompletionsCompat(model).capabilities.endpointClass;
|
|
685
714
|
return model.provider === "google" || endpointClass === "google-generative-ai" || endpointClass === "google-vertex";
|
|
686
715
|
}
|
|
687
|
-
function requiresGoogleCompatToolCallThoughtSignature(model) {
|
|
688
|
-
return isGoogleGemini3ProModel(model.id) || isGoogleGemini3FlashModel(model.id);
|
|
689
|
-
}
|
|
690
716
|
const GOOGLE_COMPAT_THOUGHT_SIGNATURE_ELLIPSIS_RE = /[\u2026]|\.\.\./;
|
|
691
717
|
const GOOGLE_COMPAT_THOUGHT_SIGNATURE_BASE64_RE = /^[A-Za-z0-9+/=]+$/;
|
|
692
718
|
function hasGoogleCompatThoughtSignatureTruncationFootprint(value) {
|
|
@@ -695,17 +721,16 @@ function hasGoogleCompatThoughtSignatureTruncationFootprint(value) {
|
|
|
695
721
|
function injectToolCallThoughtSignatures(outgoingMessages, context, model) {
|
|
696
722
|
if (!isGoogleOpenAICompatModel(model)) return;
|
|
697
723
|
const sigById = /* @__PURE__ */ new Map();
|
|
698
|
-
const fallbackSig =
|
|
724
|
+
const fallbackSig = isGoogleGemini3ThinkingLevelModel(model.id) ? GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP : void 0;
|
|
699
725
|
for (const msg of context.messages ?? []) {
|
|
700
726
|
if (msg.role !== "assistant") continue;
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
for (const block of source.content) {
|
|
727
|
+
if (!Array.isArray(msg.content)) continue;
|
|
728
|
+
for (const block of msg.content) {
|
|
704
729
|
if (block.type !== "toolCall") continue;
|
|
705
730
|
const id = block.id;
|
|
706
731
|
const sig = block.thoughtSignature;
|
|
707
732
|
if (typeof id === "string" && typeof sig === "string" && sig.length > 0) {
|
|
708
|
-
const isSameRoute =
|
|
733
|
+
const isSameRoute = msg.api === model.api && msg.provider === model.provider && msg.model === model.id;
|
|
709
734
|
if (!isSameRoute && !fallbackSig) continue;
|
|
710
735
|
sigById.set(id, isSameRoute ? sig : fallbackSig ?? sig);
|
|
711
736
|
}
|
|
@@ -738,7 +763,7 @@ const COMPLETIONS_REASONING_REPLAY_FIELDS = [
|
|
|
738
763
|
"reasoning_text"
|
|
739
764
|
];
|
|
740
765
|
function stripCompletionsReasoningReplayFields(record) {
|
|
741
|
-
for (const field of COMPLETIONS_REASONING_REPLAY_FIELDS)
|
|
766
|
+
for (const field of COMPLETIONS_REASONING_REPLAY_FIELDS) delete record[field];
|
|
742
767
|
}
|
|
743
768
|
function sanitizeOpenRouterReasoningReplayFields(record) {
|
|
744
769
|
const reasoningDetails = record.reasoning_details;
|
|
@@ -746,11 +771,10 @@ function sanitizeOpenRouterReasoningReplayFields(record) {
|
|
|
746
771
|
if (reasoningDetails.length > 0 && typeof record.reasoning !== "string") record.reasoning = reasoningDetails;
|
|
747
772
|
delete record.reasoning_details;
|
|
748
773
|
} else if (reasoningDetails !== void 0 && !Array.isArray(reasoningDetails)) delete record.reasoning_details;
|
|
749
|
-
|
|
750
|
-
if ("reasoning_content" in record && (typeof record.reasoning_content !== "string" || record.reasoning_content === "")) delete record.reasoning_content;
|
|
774
|
+
for (const field of ["reasoning", "reasoning_content"]) if (field in record && (typeof record[field] !== "string" || record[field] === "")) delete record[field];
|
|
751
775
|
const reasoningText = record.reasoning_text;
|
|
752
776
|
if (typeof reasoningText === "string" && reasoningText.length > 0 && typeof record.reasoning !== "string" && typeof record.reasoning_content !== "string") record.reasoning = reasoningText;
|
|
753
|
-
|
|
777
|
+
delete record.reasoning_text;
|
|
754
778
|
}
|
|
755
779
|
function sanitizeReasoningContentReplayFields(record) {
|
|
756
780
|
if ("reasoning_content" in record && typeof record.reasoning_content !== "string") delete record.reasoning_content;
|
|
@@ -795,10 +819,7 @@ function getReasoningContentReplayModelIdCandidates(modelId) {
|
|
|
795
819
|
const candidates = [finalPart];
|
|
796
820
|
const colonParts = finalPart.split(":").filter(Boolean);
|
|
797
821
|
if (colonParts.length > 1) candidates.push(colonParts[0] ?? "", colonParts[colonParts.length - 1] ?? "");
|
|
798
|
-
const
|
|
799
|
-
for (let index = 0; index < baseCount; index += 1) {
|
|
800
|
-
const candidate = candidates[index];
|
|
801
|
-
if (typeof candidate !== "string") continue;
|
|
822
|
+
for (const candidate of candidates.slice()) {
|
|
802
823
|
const stripped = stripReasoningContentReplayTierSuffix(candidate);
|
|
803
824
|
if (stripped !== candidate) candidates.push(stripped);
|
|
804
825
|
}
|
|
@@ -842,11 +863,8 @@ function isKnownOpenAICompletionsEndpoint(model) {
|
|
|
842
863
|
if (!model.baseUrl.trim() || isNativeOpenAIEndpoint(model)) return true;
|
|
843
864
|
const endpointClass = resolveProviderEndpoint(model).endpointClass;
|
|
844
865
|
if (endpointClass === "openai-public" || endpointClass === "azure-openai") return true;
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
} catch {
|
|
848
|
-
return false;
|
|
849
|
-
}
|
|
866
|
+
const endpoint = URL.parse(model.baseUrl);
|
|
867
|
+
return endpoint !== null && isAzureOpenAICompatibleHost(endpoint.hostname.toLowerCase());
|
|
850
868
|
}
|
|
851
869
|
function resolveOpenAICompletionsMaxTokens(model, options) {
|
|
852
870
|
if (options?.maxTokens) return {
|
|
@@ -1262,8 +1280,16 @@ function parseDeepSeekDsmlInvokeArguments(body) {
|
|
|
1262
1280
|
const name = parseDsmlNameAttribute(parameterMatch[2] ?? "");
|
|
1263
1281
|
if (!name) continue;
|
|
1264
1282
|
const rawValue = parameterMatch[3] ?? "";
|
|
1265
|
-
if (rawValue.length === 0)
|
|
1266
|
-
|
|
1283
|
+
if (rawValue.length === 0) {
|
|
1284
|
+
const stringAttribute = Array.from((parameterMatch[2] ?? "").matchAll(/(?:^|\s)([^\s=]+)=(?:"([^"]*)"|'([^']*)'|([^\s"']+))(?=\s|$)/g)).find((attribute) => attribute[1] === "string");
|
|
1285
|
+
if ((stringAttribute?.[2] ?? stringAttribute?.[3] ?? stringAttribute?.[4]) !== "true") continue;
|
|
1286
|
+
}
|
|
1287
|
+
Object.defineProperty(args, name, {
|
|
1288
|
+
value: decodeDeepSeekDsmlText(rawValue),
|
|
1289
|
+
enumerable: true,
|
|
1290
|
+
configurable: true,
|
|
1291
|
+
writable: true
|
|
1292
|
+
});
|
|
1267
1293
|
}
|
|
1268
1294
|
if (Object.keys(args).length > 0) return args;
|
|
1269
1295
|
const trimmed = body.trim();
|
|
@@ -1361,12 +1387,8 @@ function scanDeepSeekDsmlToolBlock(text, closeToken, contentStartIndex, state) {
|
|
|
1361
1387
|
function extractToolCallThoughtSignature(toolCall) {
|
|
1362
1388
|
const tc = toolCall;
|
|
1363
1389
|
if (!tc) return;
|
|
1364
|
-
const
|
|
1365
|
-
|
|
1366
|
-
const fromFunction = tc.function?.thought_signature;
|
|
1367
|
-
if (typeof fromFunction === "string" && fromFunction.length > 0) return fromFunction;
|
|
1368
|
-
const fromToolCall = tc.thought_signature;
|
|
1369
|
-
return typeof fromToolCall === "string" && fromToolCall.length > 0 ? fromToolCall : void 0;
|
|
1390
|
+
const extra = tc.extra_content?.google;
|
|
1391
|
+
return readNonEmptyStringPreservingWhitespace(extra?.thought_signature) ?? readNonEmptyStringPreservingWhitespace(tc.function?.thought_signature) ?? readNonEmptyStringPreservingWhitespace(tc.thought_signature);
|
|
1370
1392
|
}
|
|
1371
1393
|
async function processCompletionsStream(responseStream, output, model, stream, options) {
|
|
1372
1394
|
const MAX_POST_TOOL_CALL_BUFFER_BYTES = 256e3;
|
|
@@ -1757,12 +1779,303 @@ async function processCompletionsStream(responseStream, output, model, stream, o
|
|
|
1757
1779
|
function shouldEmitOpenAICompletionsReasoning(model, options) {
|
|
1758
1780
|
if (!model.reasoning) return false;
|
|
1759
1781
|
const effort = options?.reasoningEffort ?? options?.reasoning ?? "high";
|
|
1760
|
-
|
|
1761
|
-
return true;
|
|
1782
|
+
return Boolean(effort) && isOpenAICompletionsThinkingEnabled(effort);
|
|
1762
1783
|
}
|
|
1763
1784
|
function hasOpenAICompletionsReasoningUsageActivity(rawUsage) {
|
|
1764
1785
|
const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens;
|
|
1765
1786
|
return typeof reasoningTokens === "number" && Number.isFinite(reasoningTokens) && reasoningTokens > 0;
|
|
1766
1787
|
}
|
|
1767
1788
|
//#endregion
|
|
1768
|
-
|
|
1789
|
+
//#region packages/ai/src/transports/openai-completions-transport.ts
|
|
1790
|
+
function assertOpenAICompletionsPayloadHasConversationTurn(params, model) {
|
|
1791
|
+
const messages = params.messages;
|
|
1792
|
+
if (!Array.isArray(messages) || hasOpenAICompatibleConversationTurn(messages)) return;
|
|
1793
|
+
throw new Error(`OpenAI-compatible chat payload for ${model.provider}/${model.id} contains no non-empty user or assistant messages after compaction and transport transforms; refusing to send a system/tool-only request. Start a new user turn or repair the compacted session history.`);
|
|
1794
|
+
}
|
|
1795
|
+
const SSE_DONE_LINE_RE = /^data:[ \t]*\[DONE\][ \t]*$/i;
|
|
1796
|
+
const SSE_DONE_MAX_LINE_CHARS = 1024;
|
|
1797
|
+
function createSseDoneDetector() {
|
|
1798
|
+
const decoder = new TextDecoder();
|
|
1799
|
+
let line = "";
|
|
1800
|
+
let lineOverflowed = false;
|
|
1801
|
+
let sawDone = false;
|
|
1802
|
+
const finishLine = () => {
|
|
1803
|
+
if (!lineOverflowed && SSE_DONE_LINE_RE.test(line)) sawDone = true;
|
|
1804
|
+
line = "";
|
|
1805
|
+
lineOverflowed = false;
|
|
1806
|
+
};
|
|
1807
|
+
const observeText = (text) => {
|
|
1808
|
+
for (const char of text) {
|
|
1809
|
+
if (char === "\n" || char === "\r") {
|
|
1810
|
+
finishLine();
|
|
1811
|
+
continue;
|
|
1812
|
+
}
|
|
1813
|
+
if (!lineOverflowed && line.length < SSE_DONE_MAX_LINE_CHARS) line += char;
|
|
1814
|
+
else lineOverflowed = true;
|
|
1815
|
+
}
|
|
1816
|
+
};
|
|
1817
|
+
return {
|
|
1818
|
+
observe(chunk) {
|
|
1819
|
+
if (!sawDone) observeText(decoder.decode(chunk, { stream: true }));
|
|
1820
|
+
},
|
|
1821
|
+
finish() {
|
|
1822
|
+
if (sawDone) return;
|
|
1823
|
+
observeText(decoder.decode());
|
|
1824
|
+
if (line || lineOverflowed) finishLine();
|
|
1825
|
+
},
|
|
1826
|
+
sawDone: () => sawDone
|
|
1827
|
+
};
|
|
1828
|
+
}
|
|
1829
|
+
function buildOpenAICompletionsClientConfig(model, headers) {
|
|
1830
|
+
const defaultQuery = {};
|
|
1831
|
+
let baseURL = model.baseUrl;
|
|
1832
|
+
let isAzureHost = false;
|
|
1833
|
+
const parsed = URL.parse(model.baseUrl);
|
|
1834
|
+
if (parsed) {
|
|
1835
|
+
isAzureHost = isAzureOpenAICompatibleHost(parsed.hostname.toLowerCase());
|
|
1836
|
+
parsed.searchParams.forEach((value, key) => {
|
|
1837
|
+
if (value) defaultQuery[key] = value;
|
|
1838
|
+
});
|
|
1839
|
+
parsed.search = "";
|
|
1840
|
+
baseURL = parsed.toString().replace(/\/$/, "");
|
|
1841
|
+
}
|
|
1842
|
+
if (isAzureHost) {
|
|
1843
|
+
const apiVersionHeader = Object.keys(headers).find((key) => key.toLowerCase() === "api-version");
|
|
1844
|
+
if (apiVersionHeader) {
|
|
1845
|
+
const apiVersion = headers[apiVersionHeader]?.trim();
|
|
1846
|
+
delete headers[apiVersionHeader];
|
|
1847
|
+
if (apiVersion && !defaultQuery["api-version"]) defaultQuery["api-version"] = apiVersion;
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
return {
|
|
1851
|
+
baseURL: resolveOpenAIClientBaseUrl(model, baseURL),
|
|
1852
|
+
defaultHeaders: headers,
|
|
1853
|
+
defaultQuery: Object.keys(defaultQuery).length > 0 ? defaultQuery : void 0
|
|
1854
|
+
};
|
|
1855
|
+
}
|
|
1856
|
+
function createDirectCompletionsEventStream(output, stream) {
|
|
1857
|
+
const finishedBlocks = /* @__PURE__ */ new Set();
|
|
1858
|
+
const contentIndices = /* @__PURE__ */ new WeakMap();
|
|
1859
|
+
let openTextBlock;
|
|
1860
|
+
let openThinkingBlock;
|
|
1861
|
+
const finishBlock = (block) => {
|
|
1862
|
+
const contentIndex = contentIndices.get(block);
|
|
1863
|
+
if (contentIndex === void 0 || finishedBlocks.has(block)) return;
|
|
1864
|
+
finishedBlocks.add(block);
|
|
1865
|
+
if (block.type === "text") {
|
|
1866
|
+
openTextBlock = void 0;
|
|
1867
|
+
stream.push({
|
|
1868
|
+
type: "text_end",
|
|
1869
|
+
contentIndex,
|
|
1870
|
+
content: block.text,
|
|
1871
|
+
partial: output
|
|
1872
|
+
});
|
|
1873
|
+
} else if (block.type === "thinking") {
|
|
1874
|
+
openThinkingBlock = void 0;
|
|
1875
|
+
stream.push({
|
|
1876
|
+
type: "thinking_end",
|
|
1877
|
+
contentIndex,
|
|
1878
|
+
content: block.thinking,
|
|
1879
|
+
partial: output
|
|
1880
|
+
});
|
|
1881
|
+
} else if (block.type === "toolCall") stream.push({
|
|
1882
|
+
type: "toolcall_end",
|
|
1883
|
+
contentIndex,
|
|
1884
|
+
toolCall: block,
|
|
1885
|
+
partial: output
|
|
1886
|
+
});
|
|
1887
|
+
};
|
|
1888
|
+
return {
|
|
1889
|
+
stream: { push(event) {
|
|
1890
|
+
if (event.type === "text_start" || event.type === "thinking_start" || event.type === "toolcall_start") {
|
|
1891
|
+
const block = output.content[event.contentIndex];
|
|
1892
|
+
if (block) {
|
|
1893
|
+
contentIndices.set(block, event.contentIndex);
|
|
1894
|
+
if (block.type === "text") openTextBlock = block;
|
|
1895
|
+
else if (block.type === "thinking") openThinkingBlock = block;
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1898
|
+
stream.push(event);
|
|
1899
|
+
} },
|
|
1900
|
+
beforeContentBlock: (nextType) => {
|
|
1901
|
+
if (openThinkingBlock) finishBlock(openThinkingBlock);
|
|
1902
|
+
if (openTextBlock && nextType !== "toolCall") finishBlock(openTextBlock);
|
|
1903
|
+
},
|
|
1904
|
+
finish(includeToolCalls) {
|
|
1905
|
+
for (const block of output.content) if (block.type !== "toolCall" || includeToolCalls) finishBlock(block);
|
|
1906
|
+
}
|
|
1907
|
+
};
|
|
1908
|
+
}
|
|
1909
|
+
function createOpenAICompletionsTransportStreamFn() {
|
|
1910
|
+
return (model, context, options) => streamOpenAICompletionsRequest(model, context, options, "managed");
|
|
1911
|
+
}
|
|
1912
|
+
function streamOpenAICompletionsRequest(model, context, options, mode) {
|
|
1913
|
+
const { eventStream, stream } = createWritableTransportEventStream();
|
|
1914
|
+
(async () => {
|
|
1915
|
+
const output = createAssistantOutput(model);
|
|
1916
|
+
const provisionalCommentaryTags = /* @__PURE__ */ new Map();
|
|
1917
|
+
let firstEventAbort;
|
|
1918
|
+
try {
|
|
1919
|
+
const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
|
|
1920
|
+
const directEmitReasoning = Boolean(mode === "direct" && model.reasoning && options?.reasoningEffort && isOpenAICompletionsThinkingEnabled(options.reasoningEffort));
|
|
1921
|
+
const cacheRetention = resolveCacheRetention(options?.cacheRetention);
|
|
1922
|
+
const policy = mode === "direct" ? {
|
|
1923
|
+
mode,
|
|
1924
|
+
compat: resolveOpenAICompletionsCompat(model),
|
|
1925
|
+
cacheRetention
|
|
1926
|
+
} : { mode };
|
|
1927
|
+
const { client, sawStreamDONE } = policy.mode === "direct" ? {
|
|
1928
|
+
client: createDirectCompletionsClient(model, context, apiKey, resolveProviderSimpleCompletionHeaders(model, options), cacheRetention === "none" ? void 0 : options?.sessionId, policy.compat),
|
|
1929
|
+
sawStreamDONE: void 0
|
|
1930
|
+
} : createManagedCompletionsClient(model, context, options, apiKey, cacheRetention);
|
|
1931
|
+
let params = buildOpenAICompletionsRequest(model, context, options, policy);
|
|
1932
|
+
const encodeBody = prepareModelRequestBody(options);
|
|
1933
|
+
const nextParams = await options?.onPayload?.(params, model);
|
|
1934
|
+
if (nextParams !== void 0) params = nextParams;
|
|
1935
|
+
if (mode === "managed") {
|
|
1936
|
+
if (options?.openclawCodeModeToolSurface === true) {
|
|
1937
|
+
const visibleToolNames = resolveCodeModeResponsesVisibleToolNames(context);
|
|
1938
|
+
enforceCodeModeResponsesToolSurface(params, visibleToolNames, void 0, codeModeToolSurfaceObserver.get(options));
|
|
1939
|
+
assertCodeModeResponsesToolSurface(params, visibleToolNames);
|
|
1940
|
+
}
|
|
1941
|
+
if (getCompat(model).requiresNonEmptyUserOrAssistantMessage) assertOpenAICompletionsPayloadHasConversationTurn(params, model);
|
|
1942
|
+
}
|
|
1943
|
+
const emitReasoning = mode === "direct" ? directEmitReasoning : shouldEmitOpenAICompletionsReasoning(model, options);
|
|
1944
|
+
firstEventAbort = createFirstStreamEventAbortController(options?.signal);
|
|
1945
|
+
const requestOptions = mode === "direct" ? {
|
|
1946
|
+
...await encodeBody(params),
|
|
1947
|
+
signal: firstEventAbort.signal,
|
|
1948
|
+
...options?.timeoutMs !== void 0 ? { timeout: options.timeoutMs } : {},
|
|
1949
|
+
maxRetries: 0
|
|
1950
|
+
} : {
|
|
1951
|
+
...buildOpenAISdkRequestOptions(model, firstEventAbort.signal, { timeoutMs: options?.timeoutMs }),
|
|
1952
|
+
...await encodeBody(params)
|
|
1953
|
+
};
|
|
1954
|
+
const { data: responseStream, response } = await client.chat.completions.create(params, requestOptions).withResponse();
|
|
1955
|
+
const hookedResponseStream = withProviderResponseHook({
|
|
1956
|
+
stream: responseStream,
|
|
1957
|
+
signal: firstEventAbort.signal,
|
|
1958
|
+
abort: firstEventAbort.abort,
|
|
1959
|
+
hook: createOpenAIProviderAcceptanceHook(options, response, model),
|
|
1960
|
+
onReady: () => stream.push({
|
|
1961
|
+
type: "start",
|
|
1962
|
+
partial: output
|
|
1963
|
+
})
|
|
1964
|
+
});
|
|
1965
|
+
const directEvents = mode === "direct" ? createDirectCompletionsEventStream(output, stream) : void 0;
|
|
1966
|
+
try {
|
|
1967
|
+
await processCompletionsStream(hookedResponseStream, output, model, directEvents?.stream ?? stream, {
|
|
1968
|
+
...directEvents ? {
|
|
1969
|
+
mode: "direct",
|
|
1970
|
+
beforeContentBlock: directEvents.beforeContentBlock,
|
|
1971
|
+
provisionalCommentaryTags
|
|
1972
|
+
} : { mode: "managed" },
|
|
1973
|
+
signal: options?.signal,
|
|
1974
|
+
emitReasoning,
|
|
1975
|
+
strictReasoningTags: reasoningTagTextPolicy.isStrict(options),
|
|
1976
|
+
firstEventTimeoutMs: getFirstStreamEventTimeoutMs(options),
|
|
1977
|
+
abortFirstEventStream: firstEventAbort.abort,
|
|
1978
|
+
onFirstEventTimeout: getFirstStreamEventTimeoutHandler(options),
|
|
1979
|
+
sawStreamDONE
|
|
1980
|
+
});
|
|
1981
|
+
if (directEvents) {
|
|
1982
|
+
if (options?.signal?.aborted) throw transportAbortError(options.signal);
|
|
1983
|
+
if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error(output.errorMessage || (output.stopReason === "aborted" ? "Request was aborted" : "Provider returned an invalid tool call"));
|
|
1984
|
+
}
|
|
1985
|
+
} catch (error) {
|
|
1986
|
+
directEvents?.finish(false);
|
|
1987
|
+
throw error;
|
|
1988
|
+
}
|
|
1989
|
+
directEvents?.finish(output.stopReason === "toolUse");
|
|
1990
|
+
finalizeTransportStream({
|
|
1991
|
+
stream,
|
|
1992
|
+
output,
|
|
1993
|
+
signal: options?.signal
|
|
1994
|
+
});
|
|
1995
|
+
} catch (error) {
|
|
1996
|
+
failTransportStream({
|
|
1997
|
+
stream,
|
|
1998
|
+
output,
|
|
1999
|
+
signal: options?.signal,
|
|
2000
|
+
error,
|
|
2001
|
+
cleanup: () => {
|
|
2002
|
+
if (mode === "managed") output.stopReason = options?.signal?.aborted ? "aborted" : "error";
|
|
2003
|
+
finalizeOpenAICompletionsToolCalls(output, { allowSilentToolCallPromotion: false });
|
|
2004
|
+
clearPendingCommentaryText(provisionalCommentaryTags);
|
|
2005
|
+
tagUnresolvedTextAsCommentary(output);
|
|
2006
|
+
if (mode === "direct") for (const block of output.content) {
|
|
2007
|
+
delete block.index;
|
|
2008
|
+
delete block.partialArgs;
|
|
2009
|
+
delete block.streamIndex;
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
2012
|
+
});
|
|
2013
|
+
} finally {
|
|
2014
|
+
firstEventAbort?.dispose();
|
|
2015
|
+
}
|
|
2016
|
+
})();
|
|
2017
|
+
return eventStream;
|
|
2018
|
+
}
|
|
2019
|
+
function createDirectCompletionsClient(model, context, apiKey, optionsHeaders, sessionId, compat) {
|
|
2020
|
+
if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
|
|
2021
|
+
const headers = { ...model.headers };
|
|
2022
|
+
if (model.provider === "github-copilot") Object.assign(headers, buildCopilotDynamicHeaders(context.messages));
|
|
2023
|
+
if (sessionId && compat.sessionAffinity !== "none") {
|
|
2024
|
+
if (compat.sessionAffinity === "openrouter") headers["x-session-id"] = sessionId;
|
|
2025
|
+
else {
|
|
2026
|
+
headers.session_id = sessionId;
|
|
2027
|
+
headers["x-client-request-id"] = sessionId;
|
|
2028
|
+
headers["x-session-affinity"] = sessionId;
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
return createOpenAIProviderClient(model, apiKey, headers, optionsHeaders);
|
|
2032
|
+
}
|
|
2033
|
+
function createManagedCompletionsClient(model, context, options, apiKey, cacheRetention) {
|
|
2034
|
+
const turnState = resolveProviderTransportTurnState(model, {
|
|
2035
|
+
sessionId: options?.sessionId,
|
|
2036
|
+
turnId: randomUUID(),
|
|
2037
|
+
attempt: 1,
|
|
2038
|
+
transport: "stream"
|
|
2039
|
+
});
|
|
2040
|
+
const optionHeaders = resolveOpencodeSessionHeaders(model, options);
|
|
2041
|
+
const turnHeaders = filterProviderTurnHeadersForExplicitOpencodeSession(model, options, turnState?.headers);
|
|
2042
|
+
const doneDetector = createSseDoneDetector();
|
|
2043
|
+
const baseFetch = buildGuardedModelFetch(model);
|
|
2044
|
+
const doneDetectingFetch = async (url, init) => {
|
|
2045
|
+
const response = await baseFetch(url, init);
|
|
2046
|
+
if (!response.body || !response.ok) return response;
|
|
2047
|
+
if (typeof TransformStream === "undefined" || !response.body.pipeThrough) return response;
|
|
2048
|
+
const transformed = response.body.pipeThrough(new TransformStream({
|
|
2049
|
+
transform(chunk, controller) {
|
|
2050
|
+
doneDetector.observe(chunk);
|
|
2051
|
+
controller.enqueue(chunk);
|
|
2052
|
+
},
|
|
2053
|
+
flush() {
|
|
2054
|
+
doneDetector.finish();
|
|
2055
|
+
}
|
|
2056
|
+
}));
|
|
2057
|
+
return new Response(transformed, {
|
|
2058
|
+
headers: response.headers,
|
|
2059
|
+
status: response.status,
|
|
2060
|
+
statusText: response.statusText
|
|
2061
|
+
});
|
|
2062
|
+
};
|
|
2063
|
+
const clientConfig = buildOpenAICompletionsClientConfig(model, buildOpenAIClientHeaders(model, context, {
|
|
2064
|
+
...turnHeaders,
|
|
2065
|
+
...optionHeaders
|
|
2066
|
+
}, void 0, resolvePromptCacheKey(options, cacheRetention), cacheRetention));
|
|
2067
|
+
return {
|
|
2068
|
+
client: new OpenAI({
|
|
2069
|
+
apiKey,
|
|
2070
|
+
baseURL: clientConfig.baseURL,
|
|
2071
|
+
dangerouslyAllowBrowser: true,
|
|
2072
|
+
defaultHeaders: clientConfig.defaultHeaders,
|
|
2073
|
+
defaultQuery: clientConfig.defaultQuery,
|
|
2074
|
+
fetch: doneDetectingFetch,
|
|
2075
|
+
...buildOpenAISdkClientOptions(model)
|
|
2076
|
+
}),
|
|
2077
|
+
sawStreamDONE: doneDetector.sawDone
|
|
2078
|
+
};
|
|
2079
|
+
}
|
|
2080
|
+
//#endregion
|
|
2081
|
+
export { flattenCompletionMessagesToStringContent as a, hasOpenAICompatibleConversationTurn as c, createDeepSeekTextFilter as d, convertMessages as i, canonicalizeMaxTokensParam as l, streamOpenAICompletionsRequest as n, stripCompletionMessagesToRoleContent as o, buildOpenAICompletionsParams as r, applyCompletionsAnthropicCacheControl as s, createOpenAICompletionsTransportStreamFn as t, resolveMaxTokensParam as u };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "./types-
|
|
1
|
+
import { N as OpenAICompletionsCompat, k as Model, l as CacheRetention } from "./types-DvzmWW8J.mjs";
|
|
2
|
+
import "./types-BuiEBM3u.mjs";
|
|
3
3
|
//#region packages/ai/src/providers/openai-prompt-cache.d.ts
|
|
4
4
|
/** Selects documented lifetime fields shared by Responses and Chat Completions. */
|
|
5
5
|
declare function resolveOpenAIPromptCacheParams(model: Pick<Model, "id" | "provider" | "baseUrl">, cacheRetention: CacheRetention, compat: Required<Pick<OpenAICompletionsCompat, "supportsPromptCacheKey" | "supportsLongCacheRetention">>): {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as isNativeOpenAIEndpoint } from "./openai-completions-compat-
|
|
1
|
+
import { n as isNativeOpenAIEndpoint } from "./openai-completions-compat-BdmlhD4u.mjs";
|
|
2
2
|
//#region packages/normalization-core/src/code-points.ts
|
|
3
3
|
/** Truncates to a nonnegative code-point budget; grapheme clusters may be split. */
|
|
4
4
|
function truncateCodePoints(text, maxCodePoints) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import "./index-
|
|
2
|
-
import {
|
|
3
|
-
import "./provider-options-
|
|
4
|
-
import { i as ReplayableResponseCompactionItem,
|
|
1
|
+
import "./index-a8e_oKnu.mjs";
|
|
2
|
+
import { a as AssistantMessage, k as Model } from "./types-DvzmWW8J.mjs";
|
|
3
|
+
import "./provider-options-D5ABCV_l.mjs";
|
|
4
|
+
import { i as ReplayableResponseCompactionItem, l as OpenAIResponsesCompactionOutput, r as OpenAIResponsesReasoningReplayMetadata } from "./openai-responses-contracts-Br5IIw_h.mjs";
|
|
5
5
|
import "openai/resources/responses/responses.js";
|
|
6
6
|
//#region packages/ai/src/transports/openai-responses-compaction-replay.d.ts
|
|
7
7
|
declare function captureOpenAIResponsesCompaction(output: Pick<AssistantMessage, "providerReplay">, item: ReplayableResponseCompactionItem, boundary: number | "retained-users", model: Model, captureMetadata?: OpenAIResponsesReasoningReplayMetadata, compactedOutput?: OpenAIResponsesCompactionOutput): void;
|