@openclaw/ai 2026.8.1-beta.3 → 2026.9.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/dist/{anthropic-B8KwTtlb.mjs → anthropic-DI4PZKKB.mjs} +18 -16
- package/dist/{anthropic-compaction-replay-4Zx7-aCr.mjs → anthropic-compaction-replay-nhKaCXu6.mjs} +8 -12
- package/dist/{anthropic-payload-policy-CSx7MoKH.d.mts → anthropic-payload-policy-B_0n0enE.d.mts} +2 -1
- package/dist/{api-registry-DFxSnFqG.d.mts → api-registry-CTd8NzcD.d.mts} +2 -1
- package/dist/{azure-openai-responses-Aa4mVcYG.mjs → azure-openai-responses-D8dI0ekg.mjs} +3 -3
- package/dist/diagnostics.d.mts +0 -1
- package/dist/diagnostics.mjs +1 -1
- package/dist/event-stream-BKp4fOt_.d.mts +1 -0
- package/dist/{event-stream-D91-ohD_.d.mts → event-stream-LiXePESD.d.mts} +1 -2
- package/dist/event-stream.d.mts +2 -1
- package/dist/{google-yDRnipeq.mjs → google-Od-LLdVK.mjs} +3 -3
- package/dist/{google-shared-M1dl64nz.mjs → google-shared-Bgr9lFPw.mjs} +14 -7
- package/dist/{google-vertex-DCJHM_a5.mjs → google-vertex-aerRSXc4.mjs} +4 -4
- package/dist/{host-DF_yxOsA.mjs → host-D51fmkH6.mjs} +4 -8
- package/dist/{host-DJq_FGcz.d.mts → host-DsbPMFU6.d.mts} +3 -3
- package/dist/index-Qbej8io0.d.mts +3 -0
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +2 -3
- package/dist/internal/anthropic.d.mts +5 -4
- package/dist/internal/anthropic.mjs +4 -4
- 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 +5 -5
- package/dist/internal/openai.mjs +8 -7
- package/dist/internal/runtime.d.mts +16 -5
- package/dist/internal/runtime.mjs +6 -6
- package/dist/internal/shared.d.mts +2 -2
- package/dist/internal/shared.mjs +3 -3
- package/dist/{json-parse-CDnesDM_.mjs → json-parse-BuAJEbdW.mjs} +18 -2
- package/dist/{mistral-D6hRXI7A.mjs → mistral-EiHdymeb.mjs} +17 -21
- package/dist/{openai-chatgpt-responses-C339VIfT.mjs → openai-chatgpt-responses-DHpF9o1e.mjs} +28 -11
- package/dist/openai-completions-EFPiUGfS.mjs +399 -0
- package/dist/{openai-completions-compat-B0KTleXp.d.mts → openai-completions-compat-BefmHT26.d.mts} +3 -3
- package/dist/openai-completions-stream-DUlGwRMz.mjs +1621 -0
- package/dist/{openai-responses-BXEcr-Tp.mjs → openai-responses-BogP8OjX.mjs} +6 -5
- package/dist/{openai-responses-contracts-CD75pQ0m.d.mts → openai-responses-contracts-Dvj_UtPy.d.mts} +3 -3
- package/dist/{openai-responses-contracts-DvILoqBk.mjs → openai-responses-contracts-QUY12X0B.mjs} +4 -18
- package/dist/{openai-responses-payload-policy-BDo8CQsx.mjs → openai-responses-payload-policy-D8EdimYe.mjs} +3 -7
- package/dist/{openai-responses-prompt-observer-internal-BG-1AsBI.mjs → openai-responses-prompt-observer-internal-Cd4hJG-S.mjs} +3 -2
- package/dist/{openai-responses-shared-Cvt5MgEm.mjs → openai-responses-shared-DJThc6jW.mjs} +150 -1362
- package/dist/openai-stop-reason-Drnn_6Qj.mjs +28 -0
- package/dist/openai-tool-schema-ho-hIkQf.mjs +1695 -0
- package/dist/{provider-error-C8mBRJDl.mjs → provider-error-DDOs_Bz0.mjs} +1 -3
- package/dist/{provider-options-Cc5ZQ6Aa.d.mts → provider-options-MdMBLzlU.d.mts} +4 -3
- package/dist/{provider-transcript-transform--gtf0ZbR.mjs → provider-transcript-transform-C01bQ5a3.mjs} +1 -1
- package/dist/provider-types.d.mts +5 -3
- package/dist/providers.d.mts +1 -2
- package/dist/providers.mjs +9 -9
- package/dist/{sanitize-unicode-BP7HLLZn.mjs → sanitize-unicode-DCkltN94.mjs} +1 -2
- package/dist/simple-options-CFj7x3J4.mjs +118 -0
- package/dist/{anthropic-BQXQudmA.mjs → src-Bu3FiFAG.mjs} +1 -0
- package/dist/{streaming-byte-guard-BrbkbwUu.mjs → streaming-byte-guard-CC-HMn_u.mjs} +5 -6
- package/dist/string-normalization--fwJ4S2q.mjs +16 -0
- package/dist/{tool-schema-json-projection-FEr-jOoZ.mjs → tool-schema-json-projection-qvTEs5Am.mjs} +2 -2
- package/dist/{simple-options-oqsXB6U3.mjs → transport-stream-shared-ljShVIZB.mjs} +10 -118
- package/dist/transport-stream-shared-rvaCyFYt.d.mts +138 -0
- package/dist/{transport-utils-Bv0FHkd0.mjs → transport-utils-LJ1_rbi-.mjs} +8 -5
- package/dist/transports.d.mts +23 -117
- package/dist/transports.mjs +43 -1038
- package/dist/{types-DTAP49HF.d.mts → types-DhLoJbFm.d.mts} +34 -17
- package/dist/types-GiAjXatj.d.mts +1 -0
- package/dist/types.d.mts +4 -3
- package/dist/types.mjs +1 -2
- package/dist/utf16-slice-qz3nsy87.mjs +84 -0
- package/dist/{validation-DYNNrU9u.d.mts → validation-Dk7q7NMN.d.mts} +1 -2
- package/dist/validation.d.mts +1 -1
- package/package.json +5 -5
- package/dist/event-stream-BVVgDSdq.d.mts +0 -1
- package/dist/headers-B_e4-1J0.mjs +0 -9
- package/dist/index-BVVgDSdq.d.mts +0 -1
- package/dist/openai-completions-D88orSJ9.mjs +0 -632
- package/dist/openai-stop-reason-9OONKyAm.mjs +0 -579
- package/dist/openai-tool-projection-CHGLt03m.mjs +0 -426
- package/dist/record-coerce-DdXsgUd_.mjs +0 -23
- package/dist/src-D2H6yKkH.mjs +0 -2
- package/dist/stream-first-event-timeout-DvDeSucC.d.mts +0 -29
- package/dist/string-coerce-fsri9iCu.mjs +0 -34
- package/dist/types-BVVgDSdq.d.mts +0 -1
- package/dist/utf16-slice-CvGodqok.mjs +0 -29
package/dist/transports.mjs
CHANGED
|
@@ -1,30 +1,29 @@
|
|
|
1
1
|
import { n as getEnvApiKey } from "./env-api-keys-DrgeBuva.mjs";
|
|
2
|
-
import { d as resolveClaudeSonnet5ModelIdentity, g as supportsClaudeNativeXhighEffort, p as supportsClaudeAdaptiveThinking, u as resolveClaudeOpus5ModelIdentity } from "./
|
|
3
|
-
import {
|
|
4
|
-
import { r as calculateCost } from "./sanitize-unicode-
|
|
5
|
-
import { S as usesClaudeStreamingRefusalContract, _ as prepareClaudeNoPrefillRequestContext, a as describeToolResultMediaPlaceholder, c as extractToolResultText, d as isImageWithMediaPayload, f as ANTHROPIC_CLAUDE_CODE_BILLING_SYSTEM_BLOCK, g as mapAnthropicStopReason, h as defaultsClaudeAdaptiveThinking, m as applyClaudeRequestContract, n as getAiTransportHost, p as ANTHROPIC_CLAUDE_CODE_VERSION, r as resolveAiTransportHeaderSentinels, s as extractToolResultBlockText, v as requiresClaudeAdaptiveThinking, x as usesClaudeFable5MessagesContract, y as resolveAnthropicThinkingEffort } from "./host-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { n as toErrorObject, t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal-BG-1AsBI.mjs";
|
|
2
|
+
import { d as resolveClaudeSonnet5ModelIdentity, g as supportsClaudeNativeXhighEffort, p as supportsClaudeAdaptiveThinking, u as resolveClaudeOpus5ModelIdentity } from "./src-Bu3FiFAG.mjs";
|
|
3
|
+
import { c as normalizeLowercaseStringOrEmpty, o as isRecord, s as hasNonEmptyString } from "./utf16-slice-qz3nsy87.mjs";
|
|
4
|
+
import { r as calculateCost } from "./sanitize-unicode-DCkltN94.mjs";
|
|
5
|
+
import { S as usesClaudeStreamingRefusalContract, _ as prepareClaudeNoPrefillRequestContext, a as describeToolResultMediaPlaceholder, c as extractToolResultText, d as isImageWithMediaPayload, f as ANTHROPIC_CLAUDE_CODE_BILLING_SYSTEM_BLOCK, g as mapAnthropicStopReason, h as defaultsClaudeAdaptiveThinking, m as applyClaudeRequestContract, n as getAiTransportHost, p as ANTHROPIC_CLAUDE_CODE_VERSION, r as resolveAiTransportHeaderSentinels, s as extractToolResultBlockText, v as requiresClaudeAdaptiveThinking, x as usesClaudeFable5MessagesContract, y as resolveAnthropicThinkingEffort } from "./host-D51fmkH6.mjs";
|
|
6
|
+
import { i as canonicalizeBase64, o as stableStringify } from "./provider-error-DDOs_Bz0.mjs";
|
|
7
|
+
import { n as toErrorObject, t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal-Cd4hJG-S.mjs";
|
|
9
8
|
import { r as asNonNegativeFiniteNumber } from "./number-coercion-H9qHik3g.mjs";
|
|
10
|
-
import {
|
|
11
|
-
import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
|
|
9
|
+
import { n as uniqueStrings } from "./string-normalization--fwJ4S2q.mjs";
|
|
12
10
|
import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
|
|
13
|
-
import {
|
|
14
|
-
import { a as resolveProviderEndpoint, c as transformTransportMessages, i as resolveOpenAIStrictToolSetting, n as buildGuardedModelFetch
|
|
15
|
-
import {
|
|
16
|
-
import { a as
|
|
11
|
+
import { f as sortPromptCacheToolsByName, l as stripSystemPromptCacheBoundary, t as adjustMaxTokensForThinking } from "./simple-options-CFj7x3J4.mjs";
|
|
12
|
+
import { a as resolveProviderEndpoint, c as transformTransportMessages, i as resolveOpenAIStrictToolSetting, n as buildGuardedModelFetch } from "./tool-schema-json-projection-qvTEs5Am.mjs";
|
|
13
|
+
import { a as isGoogleGemini3FlashModel, c as parseRetryAfterSeconds, f as resolveModelHeaderSentinels$1, h as supportsModelTools, i as isCodeModeModelVisibleToolName, l as readResponseTextSnippet, m as sha256Hex, n as createAbortError$1, o as isGoogleGemini3ProModel, p as resolveSecretSentinel, r as estimateStringChars, t as MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, u as redactIdentifier } from "./transport-utils-LJ1_rbi-.mjs";
|
|
14
|
+
import { A as resolveAnthropicImageMediaType, C as readAnthropicFallbackBoundary, D as usesFoundryBearerAuth, E as omitFoundryBearerCredentialHeaders, F as resolveAnthropicPayloadPolicy, I as resolveAnthropicServerCompactionPlan, M as applyAnthropicEphemeralCacheControlMarkers, N as applyAnthropicPayloadPolicyToParams, O as createAnthropicInlineImageBudget, P as resolveAnthropicEphemeralCacheControl, S as applyAnthropicFallbackBoundary, T as applyAnthropicRefusal, _ as ANTHROPIC_OMITTED_REASONING_TEXT, a as applyAnthropicMessageDeltaUsage, b as ANTHROPIC_SERVER_SIDE_FALLBACK_BETA, d as normalizeAnthropicToolCallId, f as normalizeAnthropicToolChoice, g as toClaudeCodeToolName, h as resolveOriginalAnthropicToolName, i as suppressAnthropicCompaction, j as applyAnthropicCacheControlToMessages, k as normalizeAnthropicInlineContent, m as reconcileAnthropicToolChoice, n as createCompactionCapture, o as applyAnthropicMessageStartUsage, p as projectAnthropicTools, r as isAnthropicReplayRejection, t as buildAnthropicReplayPlan, v as findActiveAnthropicToolTurnAssistantIndex, w as resolveAnthropicFallbackServingModelCost, y as ANTHROPIC_SERVER_SIDE_FALLBACKS } from "./anthropic-compaction-replay-nhKaCXu6.mjs";
|
|
15
|
+
import { S as quoteUnsafeIntegerLiterals, _ as transportAbortError, a as createWritableTransportEventStream, b as parseJsonObjectPreservingUnsafeIntegers, c as finalizeTransportStream, d as notifyProviderHttpMetadata, f as notifyProviderHttpResponse, g as sanitizeTransportPayloadText, h as sanitizeNonEmptyTransportPayloadText, i as createEmptyTransportUsage, l as mergeTransportHeaders, m as parseTerminalToolCallArguments, n as coerceTransportToolCallArguments, o as failTransportStream, p as notifyProviderStreamOpened, r as copyProviderAcceptanceObserver, s as finalizeTerminalToolCallArguments, t as assignTransportErrorDetails, u as mergeTransportMetadata, v as withProviderAcceptanceObserver, x as parseJsonPreservingUnsafeIntegers, y as withProviderResponseHook } from "./transport-stream-shared-ljShVIZB.mjs";
|
|
16
|
+
import { C as createDeepSeekTextFilter, E as tagUnresolvedTextAsCommentary, S as shouldOmitOllamaCompatResponseFormat, T as tagPendingCommentaryText, _ as hasToolCallHistory, a as buildOpenAISdkClientOptions, b as resolveOpenAICompletionsCompat, c as filterCodeModePayloadTools, d as readCodeModePayloadToolName, f as resolveCodeModeResponsesVisibleToolNames, g as convertMessages, h as resolveOpenAIReasoningEffortMap, i as buildOpenAIClientHeaders, l as getCompat, m as usesNativeOpenAICodexResponsesBackend, n as shouldEmitOpenAICompletionsReasoning, o as buildOpenAISdkRequestOptions, p as resolveOpenAIStrictToolFlagWithDiagnostics, r as assertCodeModeResponsesToolSurface, s as enforceCodeModeResponsesToolSurface, t as processCompletionsStream, u as isOpenAICodexResponsesModel, v as finalizeOpenAICompletionsToolCalls, x as resolveOpenAICompletionsResponseFormat, y as detectOpenAICompletionsCompat } from "./openai-completions-stream-DUlGwRMz.mjs";
|
|
17
17
|
import { t as createDeferredEventBuffer } from "./deferred-event-buffer-DAvyP7qA.mjs";
|
|
18
|
-
import {
|
|
18
|
+
import { r as parseStreamingJson, t as createToolArgumentPreviewSchedule } from "./json-parse-BuAJEbdW.mjs";
|
|
19
19
|
import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
|
|
20
|
-
import { a as isGoogleGemini3FlashModel, c as readResponseTextSnippet, d as resolveModelHeaderSentinels$1, f as resolveSecretSentinel, i as isCodeModeModelVisibleToolName, l as redactIdentifier, m as supportsModelTools, n as createAbortError$1, o as isGoogleGemini3ProModel, p as sha256Hex, r as estimateStringChars, s as parseRetryAfterSeconds, t as MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE } from "./transport-utils-Bv0FHkd0.mjs";
|
|
21
20
|
import { t as googleFlashSupportsMinimalThinking } from "./google-thinking-level-C-V3tecN.mjs";
|
|
22
|
-
import { B as buildResponsesInputMessage, C as summarizeResponsesTools, G as suppressOpenAIResponsesCompaction, H as createOpenAIResponsesAssistantOutput, I as createResponsesStreamWithEncryptedContentRetry, K as resolveReplayableResponsesMessageId, L as isInvalidEncryptedContentError, R as resolveAzureOpenAIApiVersion, S as summarizeResponsesPayload, U as buildOpenAIResponsesReasoningReplayMetadata, V as convertResponsesMessages, W as captureOpenAIResponsesCompaction, Y as
|
|
21
|
+
import { B as buildResponsesInputMessage, C as summarizeResponsesTools, G as suppressOpenAIResponsesCompaction, H as createOpenAIResponsesAssistantOutput, I as createResponsesStreamWithEncryptedContentRetry, J as resolveModelPayloadDebugMode, K as resolveReplayableResponsesMessageId, L as isInvalidEncryptedContentError, R as resolveAzureOpenAIApiVersion, S as summarizeResponsesPayload, U as buildOpenAIResponsesReasoningReplayMetadata, V as convertResponsesMessages, W as captureOpenAIResponsesCompaction, Y as resolveModelSseDebugMode, _ as safeDebugValue, b as summarizeOpenAITransportError, c as processResponsesStream, f as observeResponsesStream, g as normalizeResponsesFailedEvent, h as logResponsesFailedNoDetails, m as buildResponsesFailedNoDetailsObservation, n as applyResponsesServiceTierPricing, p as ResponsesStreamFailure, q as emitModelTransportDebug, v as stringifyRedactedEvent, x as summarizeResponsesFailedNoDetailsObservation, y as stringifyRedactedPayload, z as resolveNextResponsesEncryptedContentAttempt } from "./openai-responses-shared-DJThc6jW.mjs";
|
|
23
22
|
import { t as codeModeToolSurfaceObserver } from "./provider-options-AvldWZt8.mjs";
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import { t as
|
|
27
|
-
import { i as resolveOpenAIResponsesServerCompactionPlan, n as resolveOpenAIResponsesCompactEndpointPlan, r as resolveOpenAIResponsesPayloadPolicy, t as applyOpenAIResponsesPayloadPolicy } from "./openai-responses-payload-policy-
|
|
23
|
+
import { A as readOpenAICompletionsReasoningBatch, C as createOpenAIProviderAcceptanceHook, D as measureUtf8AppendBytes, E as log, M as resolvePromptCacheKey, N as throwIfModelStreamAborted, O as parseOpenAICompletionsUsage, S as createModelStreamCooperativeScheduler, T as isOpenAICompletionsThinkingEnabled, b as reconcileOpenAIResponsesToolChoice, j as resolveOpenAIClientBaseUrl, k as readOpenAICompletionsContentDeltas, r as normalizeOpenAIStrictToolParameters, v as projectOpenAITools, w as createOpenAIResponseHook, x as GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, y as reconcileOpenAICompletionsToolChoice } from "./openai-tool-schema-ho-hIkQf.mjs";
|
|
24
|
+
import { i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-MK28puvq.mjs";
|
|
25
|
+
import { _ as isOpenAIGpt56Model, d as OpenAIResponsesWebSocketSafeRetryError, g as isOpenAIGpt55Model, h as isOpenAIGpt54MiniModel, i as OPENAI_RESPONSES_APIS, l as OpenAIResponsesWebSocketPostDispatchError, p as parseOpenAIResponsesWebSocketServerError, r as OPENAI_CODEX_RESPONSES_DEFAULT_INSTRUCTIONS, t as AZURE_RESPONSES_FIRST_EVENT_TIMEOUT_MS, u as OpenAIResponsesWebSocketPreDispatchError, v as normalizeOpenAIReasoningEffort, y as resolveOpenAIReasoningEffortForModel } from "./openai-responses-contracts-QUY12X0B.mjs";
|
|
26
|
+
import { i as resolveOpenAIResponsesServerCompactionPlan, n as resolveOpenAIResponsesCompactEndpointPlan, r as resolveOpenAIResponsesPayloadPolicy, t as applyOpenAIResponsesPayloadPolicy } from "./openai-responses-payload-policy-D8EdimYe.mjs";
|
|
28
27
|
import { i as resolveAzureDeploymentNameFromMap, t as isOpenAICompatibleAzureResponsesBaseUrl } from "./azure-openai-responses-client-compat-C7K7QfUE.mjs";
|
|
29
28
|
import { n as registerSessionResourceCleanup } from "./session-resources-CkR4WWy1.mjs";
|
|
30
29
|
import { randomUUID } from "node:crypto";
|
|
@@ -713,6 +712,7 @@ function createAnthropicMessagesTransportStreamFn() {
|
|
|
713
712
|
}
|
|
714
713
|
const blocks = output.content;
|
|
715
714
|
const blockIndexes = /* @__PURE__ */ new Map();
|
|
715
|
+
const toolArgumentPreviewSchedules = /* @__PURE__ */ new WeakMap();
|
|
716
716
|
const sealedToolCalls = [];
|
|
717
717
|
const compactionCapture = createCompactionCapture(output, model, transportOptions);
|
|
718
718
|
const pendingThinkingSignatures = /* @__PURE__ */ new Map();
|
|
@@ -966,6 +966,7 @@ function createAnthropicMessagesTransportStreamFn() {
|
|
|
966
966
|
};
|
|
967
967
|
output.content.push(block);
|
|
968
968
|
blockIndexes.set(index, output.content.length - 1);
|
|
969
|
+
toolArgumentPreviewSchedules.set(block, createToolArgumentPreviewSchedule());
|
|
969
970
|
eventSink.push({
|
|
970
971
|
type: "toolcall_start",
|
|
971
972
|
contentIndex: output.content.length - 1,
|
|
@@ -1038,7 +1039,7 @@ function createAnthropicMessagesTransportStreamFn() {
|
|
|
1038
1039
|
if (block?.type === "toolCall" && delta?.type === "input_json_delta" && typeof delta.partial_json === "string") {
|
|
1039
1040
|
const partialJson = `${block.partialJson ?? ""}${delta.partial_json}`;
|
|
1040
1041
|
block.partialJson = partialJson;
|
|
1041
|
-
block.arguments = parseAnthropicToolCallArguments(partialJson);
|
|
1042
|
+
if (toolArgumentPreviewSchedules.get(block)?.(partialJson.length)) block.arguments = parseAnthropicToolCallArguments(partialJson);
|
|
1042
1043
|
eventSink.push({
|
|
1043
1044
|
type: "toolcall_delta",
|
|
1044
1045
|
contentIndex: index,
|
|
@@ -1153,96 +1154,6 @@ function createAnthropicMessagesTransportStreamFn() {
|
|
|
1153
1154
|
};
|
|
1154
1155
|
}
|
|
1155
1156
|
//#endregion
|
|
1156
|
-
//#region packages/ai/src/transports/deepseek-text-filter.ts
|
|
1157
|
-
/**
|
|
1158
|
-
* DeepSeek DSML streaming text filter.
|
|
1159
|
-
* Removes provider-emitted DSML tool markup while buffering split tag prefixes
|
|
1160
|
-
* across streamed chunks.
|
|
1161
|
-
*/
|
|
1162
|
-
const DSML_KINDS = [
|
|
1163
|
-
"tool_use_error",
|
|
1164
|
-
"tool_calls",
|
|
1165
|
-
"tool_call",
|
|
1166
|
-
"function_calls"
|
|
1167
|
-
];
|
|
1168
|
-
const DSML_BARS = ["|", "|"];
|
|
1169
|
-
const DSML_OPEN_TOKENS = DSML_BARS.flatMap((bar) => DSML_KINDS.map((kind) => `<${bar}DSML${bar}${kind}>`));
|
|
1170
|
-
const DSML_CLOSE_TOKENS = DSML_BARS.flatMap((bar) => DSML_KINDS.map((kind) => `</${bar}DSML${bar}${kind}>`));
|
|
1171
|
-
const MAX_OPEN_TOKEN_LEN = Math.max(...DSML_OPEN_TOKENS.map((token) => token.length));
|
|
1172
|
-
const MAX_CLOSE_TOKEN_LEN = Math.max(...DSML_CLOSE_TOKENS.map((token) => token.length));
|
|
1173
|
-
/** Create an incremental text filter that strips DeepSeek DSML tool blocks. */
|
|
1174
|
-
function createDeepSeekTextFilter() {
|
|
1175
|
-
let buffer = "";
|
|
1176
|
-
let insideDsml = false;
|
|
1177
|
-
const consume = (final) => {
|
|
1178
|
-
const output = [];
|
|
1179
|
-
const emit = (text) => {
|
|
1180
|
-
if (text) output.push(text);
|
|
1181
|
-
};
|
|
1182
|
-
while (buffer) {
|
|
1183
|
-
if (insideDsml) {
|
|
1184
|
-
const close = findEarliestToken(buffer, DSML_CLOSE_TOKENS);
|
|
1185
|
-
if (close) {
|
|
1186
|
-
buffer = buffer.slice(close.index + close.token.length);
|
|
1187
|
-
insideDsml = false;
|
|
1188
|
-
continue;
|
|
1189
|
-
}
|
|
1190
|
-
const keep = final ? 0 : Math.min(buffer.length, MAX_CLOSE_TOKEN_LEN - 1);
|
|
1191
|
-
buffer = buffer.slice(buffer.length - keep);
|
|
1192
|
-
if (final) insideDsml = false;
|
|
1193
|
-
return output;
|
|
1194
|
-
}
|
|
1195
|
-
const open = findEarliestToken(buffer, DSML_OPEN_TOKENS);
|
|
1196
|
-
if (open) {
|
|
1197
|
-
emit(buffer.slice(0, open.index));
|
|
1198
|
-
buffer = buffer.slice(open.index + open.token.length);
|
|
1199
|
-
insideDsml = true;
|
|
1200
|
-
continue;
|
|
1201
|
-
}
|
|
1202
|
-
if (final) {
|
|
1203
|
-
emit(buffer);
|
|
1204
|
-
buffer = "";
|
|
1205
|
-
return output;
|
|
1206
|
-
}
|
|
1207
|
-
const keep = longestDsmlOpenPrefixSuffixLength(buffer);
|
|
1208
|
-
const emitLength = buffer.length - keep;
|
|
1209
|
-
if (emitLength <= 0) return output;
|
|
1210
|
-
emit(buffer.slice(0, emitLength));
|
|
1211
|
-
buffer = buffer.slice(emitLength);
|
|
1212
|
-
return output;
|
|
1213
|
-
}
|
|
1214
|
-
return output;
|
|
1215
|
-
};
|
|
1216
|
-
return {
|
|
1217
|
-
push(chunk) {
|
|
1218
|
-
buffer += chunk;
|
|
1219
|
-
return consume(false);
|
|
1220
|
-
},
|
|
1221
|
-
flush() {
|
|
1222
|
-
return consume(true);
|
|
1223
|
-
}
|
|
1224
|
-
};
|
|
1225
|
-
}
|
|
1226
|
-
function findEarliestToken(text, tokens) {
|
|
1227
|
-
let best = null;
|
|
1228
|
-
for (const token of tokens) {
|
|
1229
|
-
const index = text.indexOf(token);
|
|
1230
|
-
if (index !== -1 && (!best || index < best.index)) best = {
|
|
1231
|
-
index,
|
|
1232
|
-
token
|
|
1233
|
-
};
|
|
1234
|
-
}
|
|
1235
|
-
return best;
|
|
1236
|
-
}
|
|
1237
|
-
function longestDsmlOpenPrefixSuffixLength(text) {
|
|
1238
|
-
const maxLength = Math.min(text.length, MAX_OPEN_TOKEN_LEN - 1);
|
|
1239
|
-
for (let length = maxLength; length > 0; length--) {
|
|
1240
|
-
const suffix = text.slice(text.length - length);
|
|
1241
|
-
if (DSML_OPEN_TOKENS.some((token) => token.startsWith(suffix))) return length;
|
|
1242
|
-
}
|
|
1243
|
-
return 0;
|
|
1244
|
-
}
|
|
1245
|
-
//#endregion
|
|
1246
1157
|
//#region packages/ai/src/transports/model-max-tokens-params.ts
|
|
1247
1158
|
/**
|
|
1248
1159
|
* Max-token parameter normalization across provider/native naming variants.
|
|
@@ -1541,230 +1452,6 @@ function applyCompletionsReplay(outgoingMessages, context, model, compat) {
|
|
|
1541
1452
|
});
|
|
1542
1453
|
}
|
|
1543
1454
|
//#endregion
|
|
1544
|
-
//#region packages/ai/src/transports/openai-transport-params.ts
|
|
1545
|
-
const MAX_OPENAI_STRICT_TOOL_DOWNGRADE_DIAGNOSTIC_KEYS = 256;
|
|
1546
|
-
const OPENAI_CODEX_RESPONSES_PROVIDERS = /* @__PURE__ */ new Set(["openai"]);
|
|
1547
|
-
const loggedOpenAIStrictToolDowngradeDiagnosticKeys = /* @__PURE__ */ new Set();
|
|
1548
|
-
function readToolPayloadField(record, field) {
|
|
1549
|
-
try {
|
|
1550
|
-
return Object.hasOwn(record, field) ? record[field] : void 0;
|
|
1551
|
-
} catch {
|
|
1552
|
-
return;
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1555
|
-
function readCodeModePayloadToolName(tool) {
|
|
1556
|
-
if (!isRecord(tool)) return;
|
|
1557
|
-
const name = readToolPayloadField(tool, "name");
|
|
1558
|
-
if (typeof name === "string") return name;
|
|
1559
|
-
const fn = readToolPayloadField(tool, "function");
|
|
1560
|
-
if (!isRecord(fn)) return;
|
|
1561
|
-
const fnName = readToolPayloadField(fn, "name");
|
|
1562
|
-
return typeof fnName === "string" ? fnName : void 0;
|
|
1563
|
-
}
|
|
1564
|
-
function readCodeModePayloadToolIdentity(tool, visibleToolNames, allowedHostedToolTypes) {
|
|
1565
|
-
if (!isRecord(tool)) return;
|
|
1566
|
-
const type = readToolPayloadField(tool, "type");
|
|
1567
|
-
if (typeof type === "string" && allowedHostedToolTypes?.has(type)) {
|
|
1568
|
-
try {
|
|
1569
|
-
if (Object.hasOwn(tool, "name") || Object.hasOwn(tool, "function") || Object.hasOwn(tool, "functionDeclarations") || Object.hasOwn(tool, "function_declarations")) return false;
|
|
1570
|
-
} catch {
|
|
1571
|
-
return false;
|
|
1572
|
-
}
|
|
1573
|
-
return `hosted:${type}`;
|
|
1574
|
-
}
|
|
1575
|
-
const name = readCodeModePayloadToolName(tool);
|
|
1576
|
-
return typeof name === "string" && isCodeModeModelVisibleToolName(name, visibleToolNames) ? `client:${name}` : void 0;
|
|
1577
|
-
}
|
|
1578
|
-
function readCodeModePayloadToolIdentities(payload) {
|
|
1579
|
-
if (!isRecord(payload)) return [];
|
|
1580
|
-
const tools = readToolPayloadField(payload, "tools");
|
|
1581
|
-
if (!Array.isArray(tools)) return [];
|
|
1582
|
-
return tools.flatMap((tool) => {
|
|
1583
|
-
if (!isRecord(tool)) return [];
|
|
1584
|
-
const identities = [];
|
|
1585
|
-
const name = readCodeModePayloadToolName(tool);
|
|
1586
|
-
if (name) identities.push(`client:${name}`);
|
|
1587
|
-
for (const key of ["functionDeclarations", "function_declarations"]) {
|
|
1588
|
-
const declarations = readToolPayloadField(tool, key);
|
|
1589
|
-
if (!Array.isArray(declarations)) continue;
|
|
1590
|
-
for (const declaration of declarations) {
|
|
1591
|
-
const declarationName = readCodeModePayloadToolName(declaration);
|
|
1592
|
-
if (declarationName) identities.push(`client:${declarationName}`);
|
|
1593
|
-
}
|
|
1594
|
-
}
|
|
1595
|
-
const type = readToolPayloadField(tool, "type");
|
|
1596
|
-
if (typeof type === "string" && type !== "function") identities.push(`hosted:${type}`);
|
|
1597
|
-
return identities;
|
|
1598
|
-
});
|
|
1599
|
-
}
|
|
1600
|
-
function filterCodeModePayloadTools(payload, visibleToolNames, allowedHostedToolTypes, observer) {
|
|
1601
|
-
if (!isRecord(payload)) return;
|
|
1602
|
-
const tools = readToolPayloadField(payload, "tools");
|
|
1603
|
-
if (!Array.isArray(tools)) return;
|
|
1604
|
-
const beforeToolIdentities = observer ? readCodeModePayloadToolIdentities(payload) : void 0;
|
|
1605
|
-
payload.tools = tools.flatMap((tool) => {
|
|
1606
|
-
const identity = readCodeModePayloadToolIdentity(tool, visibleToolNames, allowedHostedToolTypes);
|
|
1607
|
-
if (identity) return [tool];
|
|
1608
|
-
if (identity === false) return [];
|
|
1609
|
-
if (!isRecord(tool)) return [];
|
|
1610
|
-
const filteredGroups = {};
|
|
1611
|
-
for (const key of ["functionDeclarations", "function_declarations"]) {
|
|
1612
|
-
const declarations = readToolPayloadField(tool, key);
|
|
1613
|
-
if (!Array.isArray(declarations)) continue;
|
|
1614
|
-
const filtered = declarations.filter((declaration) => {
|
|
1615
|
-
const declarationName = readCodeModePayloadToolName(declaration);
|
|
1616
|
-
return typeof declarationName === "string" && isCodeModeModelVisibleToolName(declarationName, visibleToolNames);
|
|
1617
|
-
});
|
|
1618
|
-
if (filtered.length > 0) filteredGroups[key] = filtered;
|
|
1619
|
-
}
|
|
1620
|
-
return Object.keys(filteredGroups).length > 0 ? [filteredGroups] : [];
|
|
1621
|
-
});
|
|
1622
|
-
if (beforeToolIdentities) observer?.({
|
|
1623
|
-
beforeToolIdentities,
|
|
1624
|
-
afterToolIdentities: readCodeModePayloadToolIdentities(payload)
|
|
1625
|
-
});
|
|
1626
|
-
}
|
|
1627
|
-
function resolveCodeModeResponsesVisibleToolNames(context) {
|
|
1628
|
-
return new Set((context.tools ?? []).map(readCodeModePayloadToolName).filter((name) => typeof name === "string"));
|
|
1629
|
-
}
|
|
1630
|
-
function enforceCodeModeResponsesToolSurface(payload, visibleToolNames, allowedHostedToolTypes, observer) {
|
|
1631
|
-
if (!isRecord(payload)) return;
|
|
1632
|
-
const tools = readToolPayloadField(payload, "tools");
|
|
1633
|
-
if (!Array.isArray(tools)) return;
|
|
1634
|
-
const beforeToolIdentities = observer ? readCodeModePayloadToolIdentities(payload) : void 0;
|
|
1635
|
-
payload.tools = tools.filter((tool) => Boolean(readCodeModePayloadToolIdentity(tool, visibleToolNames, allowedHostedToolTypes)));
|
|
1636
|
-
if (beforeToolIdentities) observer?.({
|
|
1637
|
-
beforeToolIdentities,
|
|
1638
|
-
afterToolIdentities: readCodeModePayloadToolIdentities(payload)
|
|
1639
|
-
});
|
|
1640
|
-
}
|
|
1641
|
-
function assertCodeModeResponsesToolSurface(payload, visibleToolNames, allowedHostedToolTypes) {
|
|
1642
|
-
const tools = isRecord(payload) ? readToolPayloadField(payload, "tools") : void 0;
|
|
1643
|
-
if (!Array.isArray(tools)) throw new Error("Code mode payload tool surface violation: expected exec,wait; got no tools");
|
|
1644
|
-
const identities = tools.map((tool) => readCodeModePayloadToolIdentity(tool, visibleToolNames, allowedHostedToolTypes));
|
|
1645
|
-
const names = identities.flatMap((identity) => typeof identity === "string" && identity.startsWith("client:") ? [identity.slice(7)] : []).toSorted((left, right) => left.localeCompare(right));
|
|
1646
|
-
if (names.length >= 2 && identities.every((identity) => typeof identity === "string") && new Set(identities).size === identities.length && names.includes("exec") && names.includes("wait")) return;
|
|
1647
|
-
throw new Error(`Code mode payload tool surface violation: expected exec,wait plus direct-only tools; got ${names.length > 0 ? names.join(",") : "none"}`);
|
|
1648
|
-
}
|
|
1649
|
-
function buildOpenAIStrictToolDowngradeDiagnosticKey(diagnostics, context) {
|
|
1650
|
-
return sha256Hex(JSON.stringify({
|
|
1651
|
-
transport: context.transport,
|
|
1652
|
-
provider: context.model.provider ?? null,
|
|
1653
|
-
model: context.model.id ?? null,
|
|
1654
|
-
diagnostics: diagnostics.map((entry) => ({
|
|
1655
|
-
toolIndex: entry.toolIndex,
|
|
1656
|
-
toolName: entry.toolName ?? null,
|
|
1657
|
-
violations: entry.violations
|
|
1658
|
-
}))
|
|
1659
|
-
}));
|
|
1660
|
-
}
|
|
1661
|
-
function shouldLogOpenAIStrictToolDowngradeDiagnostic(diagnostics, context) {
|
|
1662
|
-
const key = buildOpenAIStrictToolDowngradeDiagnosticKey(diagnostics, context);
|
|
1663
|
-
if (loggedOpenAIStrictToolDowngradeDiagnosticKeys.has(key)) return false;
|
|
1664
|
-
if (loggedOpenAIStrictToolDowngradeDiagnosticKeys.size >= MAX_OPENAI_STRICT_TOOL_DOWNGRADE_DIAGNOSTIC_KEYS) loggedOpenAIStrictToolDowngradeDiagnosticKeys.clear();
|
|
1665
|
-
loggedOpenAIStrictToolDowngradeDiagnosticKeys.add(key);
|
|
1666
|
-
return true;
|
|
1667
|
-
}
|
|
1668
|
-
function resolveOpenAIStrictToolFlagWithDiagnostics(projection, strictSetting, context) {
|
|
1669
|
-
const strict = resolveOpenAIProjectedToolsStrictToolFlag(projection, strictSetting);
|
|
1670
|
-
if (strictSetting === true && strict === false) {
|
|
1671
|
-
const diagnostics = findOpenAIStrictToolProjectionDiagnostics(projection);
|
|
1672
|
-
getAiTransportHost().logDebug("openai-transport", () => {
|
|
1673
|
-
if (!shouldLogOpenAIStrictToolDowngradeDiagnostic(diagnostics, context)) return null;
|
|
1674
|
-
const sample = diagnostics.slice(0, 5).map((entry) => ({
|
|
1675
|
-
tool: entry.toolName ?? `tool[${entry.toolIndex}]`,
|
|
1676
|
-
violations: entry.violations.slice(0, 8)
|
|
1677
|
-
}));
|
|
1678
|
-
return {
|
|
1679
|
-
message: `OpenAI ${context.transport} tool schema strict mode downgraded to strict=false for ${context.model.provider ?? "unknown"}/${context.model.id ?? "unknown"} because ${diagnostics.length} tool schema(s) are not strict-compatible`,
|
|
1680
|
-
data: {
|
|
1681
|
-
transport: context.transport,
|
|
1682
|
-
provider: context.model.provider,
|
|
1683
|
-
model: context.model.id,
|
|
1684
|
-
incompatibleToolCount: diagnostics.length,
|
|
1685
|
-
sample
|
|
1686
|
-
}
|
|
1687
|
-
};
|
|
1688
|
-
});
|
|
1689
|
-
}
|
|
1690
|
-
return strict;
|
|
1691
|
-
}
|
|
1692
|
-
function isOpenAICodexResponsesModel(model) {
|
|
1693
|
-
return OPENAI_CODEX_RESPONSES_PROVIDERS.has(model.provider) && (model.api === "openai-chatgpt-responses" || model.api === "openclaw-openai-chatgpt-responses-transport");
|
|
1694
|
-
}
|
|
1695
|
-
function isNativeOpenAICodexResponsesBaseUrl(baseUrl) {
|
|
1696
|
-
const trimmed = typeof baseUrl === "string" ? baseUrl.trim() : "";
|
|
1697
|
-
if (!trimmed) return false;
|
|
1698
|
-
try {
|
|
1699
|
-
const url = new URL(trimmed);
|
|
1700
|
-
if (url.protocol !== "http:" && url.protocol !== "https:") return false;
|
|
1701
|
-
if (url.hostname.toLowerCase() !== "chatgpt.com") return false;
|
|
1702
|
-
const pathname = url.pathname.replace(/\/+$/u, "").toLowerCase();
|
|
1703
|
-
return [
|
|
1704
|
-
"/backend-api",
|
|
1705
|
-
"/backend-api/v1",
|
|
1706
|
-
"/backend-api/codex",
|
|
1707
|
-
"/backend-api/codex/v1"
|
|
1708
|
-
].includes(pathname);
|
|
1709
|
-
} catch {
|
|
1710
|
-
return false;
|
|
1711
|
-
}
|
|
1712
|
-
}
|
|
1713
|
-
function usesNativeOpenAICodexResponsesBackend(model) {
|
|
1714
|
-
return isOpenAICodexResponsesModel(model) && isNativeOpenAICodexResponsesBaseUrl(model.baseUrl);
|
|
1715
|
-
}
|
|
1716
|
-
function buildOpenAIClientHeaders(model, context, optionHeaders, turnHeaders, sessionId) {
|
|
1717
|
-
const providerHeaders = { ...model.headers };
|
|
1718
|
-
if (model.provider === "github-copilot") Object.assign(providerHeaders, getAiTransportHost().buildCopilotDynamicHeaders(context.messages));
|
|
1719
|
-
const callerHeaders = {
|
|
1720
|
-
...optionHeaders,
|
|
1721
|
-
...turnHeaders
|
|
1722
|
-
};
|
|
1723
|
-
const resolvedHeaders = resolveProviderRequestPolicyConfig(model, {
|
|
1724
|
-
provider: model.provider,
|
|
1725
|
-
api: model.api,
|
|
1726
|
-
baseUrl: model.baseUrl,
|
|
1727
|
-
capability: "llm",
|
|
1728
|
-
transport: "stream",
|
|
1729
|
-
providerHeaders,
|
|
1730
|
-
callerHeaders: Object.keys(callerHeaders).length > 0 ? callerHeaders : void 0,
|
|
1731
|
-
precedence: "caller-wins"
|
|
1732
|
-
}).headers ?? {};
|
|
1733
|
-
if (sessionId && !Object.keys(resolvedHeaders).some((key) => normalizeLowercaseStringOrEmpty(key) === "session_id") && usesNativeOpenAICodexResponsesBackend(model)) resolvedHeaders.session_id = clampOpenAIPromptCacheKey(sessionId) ?? sessionId;
|
|
1734
|
-
return resolvedHeaders;
|
|
1735
|
-
}
|
|
1736
|
-
function resolveOpenAISdkTimeoutMs(model, timeoutMs) {
|
|
1737
|
-
return resolveModelRequestTimeoutMs(model, timeoutMs);
|
|
1738
|
-
}
|
|
1739
|
-
function buildOpenAISdkClientOptions(model) {
|
|
1740
|
-
const timeout = resolveOpenAISdkTimeoutMs(model);
|
|
1741
|
-
return timeout === void 0 ? {} : { timeout };
|
|
1742
|
-
}
|
|
1743
|
-
function buildOpenAISdkRequestOptions(model, signal, options) {
|
|
1744
|
-
const timeout = resolveOpenAISdkTimeoutMs(model, options?.timeoutMs);
|
|
1745
|
-
const headers = options?.stream === true && usesNativeOpenAICodexResponsesBackend(model) ? { Accept: "text/event-stream" } : void 0;
|
|
1746
|
-
if (timeout === void 0 && options?.maxRetries === void 0 && !signal && !headers) return;
|
|
1747
|
-
return {
|
|
1748
|
-
...headers ? { headers } : {},
|
|
1749
|
-
...signal ? { signal } : {},
|
|
1750
|
-
...timeout !== void 0 ? { timeout } : {},
|
|
1751
|
-
...options?.maxRetries !== void 0 ? { maxRetries: options.maxRetries } : {}
|
|
1752
|
-
};
|
|
1753
|
-
}
|
|
1754
|
-
function getCompat(model) {
|
|
1755
|
-
const resolved = resolveOpenAICompletionsCompat(model);
|
|
1756
|
-
const compat = model.compat ?? {};
|
|
1757
|
-
return {
|
|
1758
|
-
...resolved,
|
|
1759
|
-
cacheControlFormat: resolved.cacheControlFormat,
|
|
1760
|
-
reasoningEffortMap: resolveOpenAIReasoningEffortMap(model, {}),
|
|
1761
|
-
openRouterRouting: resolved.openRouterRouting ?? {},
|
|
1762
|
-
vercelGatewayRouting: resolved.vercelGatewayRouting,
|
|
1763
|
-
requiresStringContent: compat.requiresStringContent ?? false,
|
|
1764
|
-
strictMessageKeys: compat.strictMessageKeys === true
|
|
1765
|
-
};
|
|
1766
|
-
}
|
|
1767
|
-
//#endregion
|
|
1768
1455
|
//#region packages/ai/src/transports/openai-completions-params.ts
|
|
1769
1456
|
function isKnownOpenAICompletionsEndpoint(model) {
|
|
1770
1457
|
if (!model.baseUrl.trim()) return true;
|
|
@@ -1776,7 +1463,7 @@ function isKnownOpenAICompletionsEndpoint(model) {
|
|
|
1776
1463
|
return false;
|
|
1777
1464
|
}
|
|
1778
1465
|
}
|
|
1779
|
-
function resolveOpenAICompletionsReasoningEffort
|
|
1466
|
+
function resolveOpenAICompletionsReasoningEffort(options) {
|
|
1780
1467
|
return options?.reasoningEffort ?? options?.reasoning ?? "high";
|
|
1781
1468
|
}
|
|
1782
1469
|
function resolveOpenAICompletionsMaxTokens(model, options) {
|
|
@@ -1975,7 +1662,7 @@ function buildOpenAICompletionsParams(model, context, options) {
|
|
|
1975
1662
|
if (clampedMaxTokens) if (compat.maxTokensField === "max_tokens") params.max_tokens = clampedMaxTokens;
|
|
1976
1663
|
else params.max_completion_tokens = clampedMaxTokens;
|
|
1977
1664
|
}
|
|
1978
|
-
const completionsReasoningEffort = resolveOpenAICompletionsReasoningEffort
|
|
1665
|
+
const completionsReasoningEffort = resolveOpenAICompletionsReasoningEffort(options);
|
|
1979
1666
|
const resolvedCompletionsReasoningEffort = completionsReasoningEffort ? resolveOpenAIReasoningEffortForModel({
|
|
1980
1667
|
model,
|
|
1981
1668
|
effort: completionsReasoningEffort,
|
|
@@ -2001,692 +1688,6 @@ function buildOpenAICompletionsParams(model, context, options) {
|
|
|
2001
1688
|
return params;
|
|
2002
1689
|
}
|
|
2003
1690
|
//#endregion
|
|
2004
|
-
//#region packages/ai/src/transports/openai-completions-dsml.ts
|
|
2005
|
-
const DEEPSEEK_DSML_BARS = ["|", "|"];
|
|
2006
|
-
const DEEPSEEK_DSML_TOOL_KINDS = [
|
|
2007
|
-
"tool_calls",
|
|
2008
|
-
"tool_call",
|
|
2009
|
-
"function_calls"
|
|
2010
|
-
];
|
|
2011
|
-
const DEEPSEEK_DSML_TOOL_OPEN_TOKENS = DEEPSEEK_DSML_BARS.flatMap((bar) => DEEPSEEK_DSML_TOOL_KINDS.map((kind) => `<${bar}DSML${bar}${kind}>`));
|
|
2012
|
-
const DEEPSEEK_DSML_TOOL_CLOSE_TOKENS = DEEPSEEK_DSML_BARS.flatMap((bar) => DEEPSEEK_DSML_TOOL_KINDS.map((kind) => `</${bar}DSML${bar}${kind}>`));
|
|
2013
|
-
const DEEPSEEK_DSML_INVOKE_OPEN_PREFIXES = DEEPSEEK_DSML_BARS.map((bar) => `<${bar}DSML${bar}invoke`);
|
|
2014
|
-
const DEEPSEEK_DSML_INVOKE_CLOSE_TOKENS = DEEPSEEK_DSML_BARS.map((bar) => `</${bar}DSML${bar}invoke>`);
|
|
2015
|
-
const DEEPSEEK_DSML_TOOL_MAX_OPEN_TOKEN_LEN = Math.max(...DEEPSEEK_DSML_TOOL_OPEN_TOKENS.map((token) => token.length));
|
|
2016
|
-
const DEEPSEEK_DSML_RECOVERY_MAX_BOUNDARY_LEN = Math.max(...DEEPSEEK_DSML_TOOL_OPEN_TOKENS.map((token) => token.length), ...DEEPSEEK_DSML_TOOL_CLOSE_TOKENS.map((token) => token.length), ...DEEPSEEK_DSML_INVOKE_OPEN_PREFIXES.map((token) => token.length), ...DEEPSEEK_DSML_INVOKE_CLOSE_TOKENS.map((token) => token.length));
|
|
2017
|
-
const MAX_DSML_RECOVERY_BUFFER_BYTES = 256e3;
|
|
2018
|
-
const DEEPSEEK_DSML_SCAN_BATCH_CHARS = 64 * 1024;
|
|
2019
|
-
function createDsmlRecoverer() {
|
|
2020
|
-
let buffer = "";
|
|
2021
|
-
let bufferBytes = 0;
|
|
2022
|
-
let bufferEndsWithHighSurrogate = false;
|
|
2023
|
-
let pendingScanChars = 0;
|
|
2024
|
-
let activeOpenToken = null;
|
|
2025
|
-
let blockScanState = {
|
|
2026
|
-
offset: 0,
|
|
2027
|
-
mode: "outer",
|
|
2028
|
-
invokeOpenStart: -1
|
|
2029
|
-
};
|
|
2030
|
-
const resetBlockScan = () => {
|
|
2031
|
-
activeOpenToken = null;
|
|
2032
|
-
pendingScanChars = 0;
|
|
2033
|
-
blockScanState = {
|
|
2034
|
-
offset: 0,
|
|
2035
|
-
mode: "outer",
|
|
2036
|
-
invokeOpenStart: -1
|
|
2037
|
-
};
|
|
2038
|
-
};
|
|
2039
|
-
const consume = (final) => {
|
|
2040
|
-
const output = [];
|
|
2041
|
-
while (buffer) {
|
|
2042
|
-
const open = activeOpenToken ? {
|
|
2043
|
-
index: 0,
|
|
2044
|
-
token: activeOpenToken
|
|
2045
|
-
} : findEarliestStringToken(buffer, DEEPSEEK_DSML_TOOL_OPEN_TOKENS);
|
|
2046
|
-
if (!open) {
|
|
2047
|
-
resetBlockScan();
|
|
2048
|
-
if (final) {
|
|
2049
|
-
output.push({
|
|
2050
|
-
kind: "text",
|
|
2051
|
-
text: buffer
|
|
2052
|
-
});
|
|
2053
|
-
buffer = "";
|
|
2054
|
-
bufferBytes = 0;
|
|
2055
|
-
bufferEndsWithHighSurrogate = false;
|
|
2056
|
-
return output;
|
|
2057
|
-
}
|
|
2058
|
-
const keep = longestDeepSeekDsmlToolOpenPrefixSuffixLength(buffer);
|
|
2059
|
-
const emitLength = buffer.length - keep;
|
|
2060
|
-
if (emitLength > 0) {
|
|
2061
|
-
const emitted = buffer.slice(0, emitLength);
|
|
2062
|
-
output.push({
|
|
2063
|
-
kind: "text",
|
|
2064
|
-
text: emitted
|
|
2065
|
-
});
|
|
2066
|
-
bufferBytes -= Buffer.byteLength(emitted, "utf8");
|
|
2067
|
-
buffer = buffer.slice(emitted.length);
|
|
2068
|
-
if (!buffer) bufferEndsWithHighSurrogate = false;
|
|
2069
|
-
}
|
|
2070
|
-
return output;
|
|
2071
|
-
}
|
|
2072
|
-
if (open.index > 0) {
|
|
2073
|
-
const prefix = buffer.slice(0, open.index);
|
|
2074
|
-
output.push({
|
|
2075
|
-
kind: "text",
|
|
2076
|
-
text: prefix
|
|
2077
|
-
});
|
|
2078
|
-
bufferBytes -= Buffer.byteLength(prefix, "utf8");
|
|
2079
|
-
buffer = buffer.slice(prefix.length);
|
|
2080
|
-
resetBlockScan();
|
|
2081
|
-
}
|
|
2082
|
-
activeOpenToken = open.token;
|
|
2083
|
-
if (blockScanState.offset === 0) blockScanState.offset = open.token.length;
|
|
2084
|
-
const blockScan = scanDeepSeekDsmlToolBlock(buffer, open.token.replace("<", "</"), open.token.length, blockScanState);
|
|
2085
|
-
if (blockScan.kind === "nested-open") throw new Error("Nested DeepSeek DSML recovery wrappers are not supported");
|
|
2086
|
-
const close = blockScan.kind === "close" ? blockScan : null;
|
|
2087
|
-
if (!close) {
|
|
2088
|
-
if (final) {
|
|
2089
|
-
output.push({
|
|
2090
|
-
kind: "text",
|
|
2091
|
-
text: buffer
|
|
2092
|
-
});
|
|
2093
|
-
buffer = "";
|
|
2094
|
-
bufferBytes = 0;
|
|
2095
|
-
bufferEndsWithHighSurrogate = false;
|
|
2096
|
-
return output;
|
|
2097
|
-
}
|
|
2098
|
-
if (bufferBytes > MAX_DSML_RECOVERY_BUFFER_BYTES) throw new Error("Exceeded DeepSeek DSML recovery buffer limit");
|
|
2099
|
-
return output;
|
|
2100
|
-
}
|
|
2101
|
-
resetBlockScan();
|
|
2102
|
-
const body = buffer.slice(open.token.length, close.index);
|
|
2103
|
-
const blockText = buffer.slice(0, close.index + close.token.length);
|
|
2104
|
-
if (Buffer.byteLength(blockText, "utf8") > MAX_DSML_RECOVERY_BUFFER_BYTES) throw new Error("Exceeded DeepSeek DSML recovery buffer limit");
|
|
2105
|
-
const recoveredToolCalls = parseDeepSeekDsmlToolCallBlock(body);
|
|
2106
|
-
if (recoveredToolCalls.length > 0) output.push(...recoveredToolCalls);
|
|
2107
|
-
else output.push({
|
|
2108
|
-
kind: "text",
|
|
2109
|
-
text: blockText
|
|
2110
|
-
});
|
|
2111
|
-
bufferBytes -= Buffer.byteLength(blockText, "utf8");
|
|
2112
|
-
buffer = buffer.slice(blockText.length);
|
|
2113
|
-
if (!buffer) bufferEndsWithHighSurrogate = false;
|
|
2114
|
-
}
|
|
2115
|
-
return output;
|
|
2116
|
-
};
|
|
2117
|
-
return {
|
|
2118
|
-
push(chunk) {
|
|
2119
|
-
const append = measureUtf8AppendBytes(bufferEndsWithHighSurrogate, chunk);
|
|
2120
|
-
bufferBytes += append.bytes;
|
|
2121
|
-
bufferEndsWithHighSurrogate = append.endsWithHighSurrogate;
|
|
2122
|
-
buffer += chunk;
|
|
2123
|
-
pendingScanChars += chunk.length;
|
|
2124
|
-
if (activeOpenToken && pendingScanChars < DEEPSEEK_DSML_SCAN_BATCH_CHARS && !chunk.includes("<") && !chunk.includes(">") && bufferBytes <= MAX_DSML_RECOVERY_BUFFER_BYTES) return [];
|
|
2125
|
-
pendingScanChars = 0;
|
|
2126
|
-
return consume(false);
|
|
2127
|
-
},
|
|
2128
|
-
flush() {
|
|
2129
|
-
return consume(true);
|
|
2130
|
-
}
|
|
2131
|
-
};
|
|
2132
|
-
}
|
|
2133
|
-
function parseDeepSeekDsmlToolCallBlock(body) {
|
|
2134
|
-
const toolCalls = [];
|
|
2135
|
-
const invokeOpenRegex = /<[||]DSML[||]invoke\b([^<>]*)>/g;
|
|
2136
|
-
let openMatch;
|
|
2137
|
-
while ((openMatch = invokeOpenRegex.exec(body)) !== null) {
|
|
2138
|
-
const invokeBodyStart = openMatch.index + openMatch[0].length;
|
|
2139
|
-
const invokeClose = findEarliestStringToken(body.slice(invokeBodyStart), ["</|DSML|invoke>", "</|DSML|invoke>"]);
|
|
2140
|
-
if (!invokeClose) break;
|
|
2141
|
-
const invokeBody = body.slice(invokeBodyStart, invokeBodyStart + invokeClose.index);
|
|
2142
|
-
invokeOpenRegex.lastIndex = invokeBodyStart + invokeClose.index + invokeClose.token.length;
|
|
2143
|
-
const invokeName = parseXmlAttribute(openMatch[1] ?? "", "name");
|
|
2144
|
-
if (!invokeName) continue;
|
|
2145
|
-
const parsedArguments = parseDeepSeekDsmlInvokeArguments(invokeBody);
|
|
2146
|
-
if (!parsedArguments) continue;
|
|
2147
|
-
toolCalls.push({
|
|
2148
|
-
kind: "toolCall",
|
|
2149
|
-
name: invokeName,
|
|
2150
|
-
arguments: parsedArguments,
|
|
2151
|
-
partialArgs: JSON.stringify(parsedArguments)
|
|
2152
|
-
});
|
|
2153
|
-
}
|
|
2154
|
-
return toolCalls;
|
|
2155
|
-
}
|
|
2156
|
-
function parseDeepSeekDsmlInvokeArguments(body) {
|
|
2157
|
-
const args = {};
|
|
2158
|
-
const parameterRegex = /<[||]DSML[||]parameter\b([^>]*)>([\s\S]*?)<\/[||]DSML[||]parameter>/g;
|
|
2159
|
-
let parameterMatch;
|
|
2160
|
-
while ((parameterMatch = parameterRegex.exec(body)) !== null) {
|
|
2161
|
-
const name = parseXmlAttribute(parameterMatch[1] ?? "", "name");
|
|
2162
|
-
if (!name) continue;
|
|
2163
|
-
const rawValue = parameterMatch[2] ?? "";
|
|
2164
|
-
if (rawValue.length === 0) continue;
|
|
2165
|
-
args[name] = decodeDeepSeekDsmlText(rawValue);
|
|
2166
|
-
}
|
|
2167
|
-
if (Object.keys(args).length > 0) return args;
|
|
2168
|
-
const trimmed = body.trim();
|
|
2169
|
-
if (!trimmed.startsWith("{")) return null;
|
|
2170
|
-
try {
|
|
2171
|
-
const parsed = JSON.parse(trimmed);
|
|
2172
|
-
if (isRecord(parsed) && Object.keys(parsed).length > 0) return parsed;
|
|
2173
|
-
} catch {
|
|
2174
|
-
return null;
|
|
2175
|
-
}
|
|
2176
|
-
return null;
|
|
2177
|
-
}
|
|
2178
|
-
const xmlAttributeRegexCache = /* @__PURE__ */ new Map();
|
|
2179
|
-
function xmlAttributeRegex(name) {
|
|
2180
|
-
const cached = xmlAttributeRegexCache.get(name);
|
|
2181
|
-
if (cached) return cached;
|
|
2182
|
-
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2183
|
-
const pattern = new RegExp(`\\b${escaped}=("([^"]*)"|'([^']*)'|([^\\s>]+))`);
|
|
2184
|
-
xmlAttributeRegexCache.set(name, pattern);
|
|
2185
|
-
return pattern;
|
|
2186
|
-
}
|
|
2187
|
-
function parseXmlAttribute(attributes, name) {
|
|
2188
|
-
const match = xmlAttributeRegex(name).exec(attributes);
|
|
2189
|
-
const value = match?.[2] ?? match?.[3] ?? match?.[4];
|
|
2190
|
-
return value ? decodeDeepSeekDsmlText(value) : null;
|
|
2191
|
-
}
|
|
2192
|
-
function decodeDeepSeekDsmlText(value) {
|
|
2193
|
-
return value.replaceAll(""", "\"").replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">").replaceAll("&", "&");
|
|
2194
|
-
}
|
|
2195
|
-
function findEarliestStringToken(text, tokens, fromIndex = 0) {
|
|
2196
|
-
let best = null;
|
|
2197
|
-
for (const token of tokens) {
|
|
2198
|
-
const index = text.indexOf(token, fromIndex);
|
|
2199
|
-
if (index !== -1 && (!best || index < best.index)) best = {
|
|
2200
|
-
index,
|
|
2201
|
-
token
|
|
2202
|
-
};
|
|
2203
|
-
}
|
|
2204
|
-
return best;
|
|
2205
|
-
}
|
|
2206
|
-
function scanDeepSeekDsmlToolBlock(text, closeToken, contentStartIndex, state) {
|
|
2207
|
-
while (state.offset < text.length) {
|
|
2208
|
-
if (state.mode === "invoke-open") {
|
|
2209
|
-
const nextOpen = text.indexOf("<", state.offset);
|
|
2210
|
-
const nextClose = text.indexOf(">", state.offset);
|
|
2211
|
-
if (nextClose === -1 && nextOpen === -1) {
|
|
2212
|
-
state.offset = text.length;
|
|
2213
|
-
return { kind: "incomplete" };
|
|
2214
|
-
}
|
|
2215
|
-
if (nextOpen !== -1 && (nextClose === -1 || nextOpen < nextClose)) {
|
|
2216
|
-
state.mode = "outer";
|
|
2217
|
-
state.offset = nextOpen;
|
|
2218
|
-
state.invokeOpenStart = -1;
|
|
2219
|
-
continue;
|
|
2220
|
-
}
|
|
2221
|
-
const invokeOpenTag = text.slice(state.invokeOpenStart, nextClose + 1);
|
|
2222
|
-
if (!/^<[||]DSML[||]invoke\b[^<>]*>$/.test(invokeOpenTag)) {
|
|
2223
|
-
state.mode = "outer";
|
|
2224
|
-
state.offset = state.invokeOpenStart + 1;
|
|
2225
|
-
state.invokeOpenStart = -1;
|
|
2226
|
-
continue;
|
|
2227
|
-
}
|
|
2228
|
-
state.mode = "invoke-body";
|
|
2229
|
-
state.offset = nextClose + 1;
|
|
2230
|
-
state.invokeOpenStart = -1;
|
|
2231
|
-
continue;
|
|
2232
|
-
}
|
|
2233
|
-
if (state.mode === "invoke-body") {
|
|
2234
|
-
const invokeClose = findEarliestStringToken(text, DEEPSEEK_DSML_INVOKE_CLOSE_TOKENS, state.offset);
|
|
2235
|
-
if (!invokeClose) {
|
|
2236
|
-
state.offset = Math.max(0, text.length - DEEPSEEK_DSML_RECOVERY_MAX_BOUNDARY_LEN + 1);
|
|
2237
|
-
return { kind: "incomplete" };
|
|
2238
|
-
}
|
|
2239
|
-
state.mode = "outer";
|
|
2240
|
-
state.offset = invokeClose.index + invokeClose.token.length;
|
|
2241
|
-
continue;
|
|
2242
|
-
}
|
|
2243
|
-
const toolOpen = findEarliestStringToken(text, DEEPSEEK_DSML_TOOL_OPEN_TOKENS, state.offset);
|
|
2244
|
-
const toolCloseIndex = text.indexOf(closeToken, state.offset);
|
|
2245
|
-
const invokeOpen = findEarliestStringToken(text, DEEPSEEK_DSML_INVOKE_OPEN_PREFIXES, state.offset);
|
|
2246
|
-
const next = [
|
|
2247
|
-
toolOpen ? {
|
|
2248
|
-
kind: "nested-open",
|
|
2249
|
-
...toolOpen
|
|
2250
|
-
} : null,
|
|
2251
|
-
toolCloseIndex === -1 ? null : {
|
|
2252
|
-
kind: "close",
|
|
2253
|
-
index: toolCloseIndex,
|
|
2254
|
-
token: closeToken
|
|
2255
|
-
},
|
|
2256
|
-
invokeOpen ? {
|
|
2257
|
-
kind: "invoke-open",
|
|
2258
|
-
...invokeOpen
|
|
2259
|
-
} : null
|
|
2260
|
-
].filter((candidate) => candidate !== null).toSorted((left, right) => left.index - right.index)[0];
|
|
2261
|
-
if (!next) {
|
|
2262
|
-
state.offset = Math.max(contentStartIndex, text.length - DEEPSEEK_DSML_RECOVERY_MAX_BOUNDARY_LEN + 1);
|
|
2263
|
-
return { kind: "incomplete" };
|
|
2264
|
-
}
|
|
2265
|
-
if (next.kind === "invoke-open") {
|
|
2266
|
-
state.mode = "invoke-open";
|
|
2267
|
-
state.invokeOpenStart = next.index;
|
|
2268
|
-
state.offset = next.index + next.token.length;
|
|
2269
|
-
continue;
|
|
2270
|
-
}
|
|
2271
|
-
return next;
|
|
2272
|
-
}
|
|
2273
|
-
return { kind: "incomplete" };
|
|
2274
|
-
}
|
|
2275
|
-
function longestDeepSeekDsmlToolOpenPrefixSuffixLength(text) {
|
|
2276
|
-
const maxLength = Math.min(text.length, DEEPSEEK_DSML_TOOL_MAX_OPEN_TOKEN_LEN - 1);
|
|
2277
|
-
for (let length = maxLength; length > 0; length -= 1) {
|
|
2278
|
-
const suffix = text.slice(text.length - length);
|
|
2279
|
-
if (DEEPSEEK_DSML_TOOL_OPEN_TOKENS.some((token) => token.startsWith(suffix))) return length;
|
|
2280
|
-
}
|
|
2281
|
-
return 0;
|
|
2282
|
-
}
|
|
2283
|
-
//#endregion
|
|
2284
|
-
//#region packages/ai/src/transports/openai-completions-stream.ts
|
|
2285
|
-
function extractToolCallThoughtSignature(toolCall) {
|
|
2286
|
-
const tc = toolCall;
|
|
2287
|
-
if (!tc) return;
|
|
2288
|
-
const fromExtra = (tc.extra_content?.google)?.thought_signature;
|
|
2289
|
-
if (typeof fromExtra === "string" && fromExtra.length > 0) return fromExtra;
|
|
2290
|
-
const fromFunction = tc.function?.thought_signature;
|
|
2291
|
-
if (typeof fromFunction === "string" && fromFunction.length > 0) return fromFunction;
|
|
2292
|
-
const fromToolCall = tc.thought_signature;
|
|
2293
|
-
return typeof fromToolCall === "string" && fromToolCall.length > 0 ? fromToolCall : void 0;
|
|
2294
|
-
}
|
|
2295
|
-
async function processCompletionsStream(responseStream, output, model, stream, options) {
|
|
2296
|
-
const MAX_POST_TOOL_CALL_BUFFER_BYTES = 256e3;
|
|
2297
|
-
const emitReasoning = options?.emitReasoning ?? true;
|
|
2298
|
-
const compat = getCompat(model);
|
|
2299
|
-
const visibleReasoningDetailTypes = new Set(compat.visibleReasoningDetailTypes);
|
|
2300
|
-
const shouldFilterDeepSeekDsmlText = compat.thinkingFormat === "deepseek";
|
|
2301
|
-
const deepSeekTextFilter = shouldFilterDeepSeekDsmlText ? createDeepSeekTextFilter() : null;
|
|
2302
|
-
const deepSeekToolCallRecoverer = shouldFilterDeepSeekDsmlText ? createDsmlRecoverer() : null;
|
|
2303
|
-
const reasoningTagTextPartitioner = createReasoningTagTextPartitioner();
|
|
2304
|
-
let currentBlock = null;
|
|
2305
|
-
let currentTextSource;
|
|
2306
|
-
let pendingInterruptedTextBlock = null;
|
|
2307
|
-
let confirmedInterruptedTextBlock = null;
|
|
2308
|
-
let pendingPostToolCallDeltas = [];
|
|
2309
|
-
let pendingPostToolCallBytes = 0;
|
|
2310
|
-
let isFlushingPendingPostToolCallDeltas = false;
|
|
2311
|
-
const toolCallBlocksByIndex = /* @__PURE__ */ new Map();
|
|
2312
|
-
const toolCallBlocksById = /* @__PURE__ */ new Map();
|
|
2313
|
-
const provisionalCommentaryTags = /* @__PURE__ */ new Map();
|
|
2314
|
-
const toolCallBlockIndices = /* @__PURE__ */ new WeakMap();
|
|
2315
|
-
let explicitVisibleTextBlocks;
|
|
2316
|
-
const normalizeToolCallDeltas = createOpenAICompletionsToolCallDeltaNormalizer();
|
|
2317
|
-
let sawStopFinishReason = false;
|
|
2318
|
-
let sawNativeToolCallDelta = false;
|
|
2319
|
-
const blockIndex = () => output.content.length - 1;
|
|
2320
|
-
const measureUtf8Bytes = (text) => Buffer.byteLength(text, "utf8");
|
|
2321
|
-
let chunkPushedEvent = false;
|
|
2322
|
-
const pushStreamEvent = (event) => {
|
|
2323
|
-
chunkPushedEvent = true;
|
|
2324
|
-
stream.push(event);
|
|
2325
|
-
};
|
|
2326
|
-
const queuePostToolCallDelta = (next) => {
|
|
2327
|
-
const nextBytes = measureUtf8Bytes(next.text);
|
|
2328
|
-
if (pendingPostToolCallBytes + nextBytes > MAX_POST_TOOL_CALL_BUFFER_BYTES) throw new Error("Exceeded post-tool-call delta buffer limit");
|
|
2329
|
-
pendingPostToolCallBytes += nextBytes;
|
|
2330
|
-
const previous = pendingPostToolCallDeltas[pendingPostToolCallDeltas.length - 1];
|
|
2331
|
-
if (!previous || previous.kind !== next.kind || previous.kind === "text" && next.kind === "text" && previous.source !== next.source) {
|
|
2332
|
-
pendingPostToolCallDeltas.push(next);
|
|
2333
|
-
return;
|
|
2334
|
-
}
|
|
2335
|
-
if (next.kind === "thinking" && previous.kind === "thinking") {
|
|
2336
|
-
if (previous.signature !== next.signature) {
|
|
2337
|
-
pendingPostToolCallDeltas.push(next);
|
|
2338
|
-
return;
|
|
2339
|
-
}
|
|
2340
|
-
previous.text += next.text;
|
|
2341
|
-
return;
|
|
2342
|
-
}
|
|
2343
|
-
previous.text += next.text;
|
|
2344
|
-
};
|
|
2345
|
-
const appendThinkingDeltaInternal = (reasoningDelta) => {
|
|
2346
|
-
if (!currentBlock || currentBlock.type !== "thinking") {
|
|
2347
|
-
currentBlock = {
|
|
2348
|
-
type: "thinking",
|
|
2349
|
-
thinking: "",
|
|
2350
|
-
...reasoningDelta.signature ? { thinkingSignature: reasoningDelta.signature } : {}
|
|
2351
|
-
};
|
|
2352
|
-
output.content.push(currentBlock);
|
|
2353
|
-
pushStreamEvent({
|
|
2354
|
-
type: "thinking_start",
|
|
2355
|
-
contentIndex: blockIndex(),
|
|
2356
|
-
partial: output
|
|
2357
|
-
});
|
|
2358
|
-
}
|
|
2359
|
-
currentBlock.thinking += reasoningDelta.text;
|
|
2360
|
-
pushStreamEvent({
|
|
2361
|
-
type: "thinking_delta",
|
|
2362
|
-
contentIndex: blockIndex(),
|
|
2363
|
-
delta: reasoningDelta.text,
|
|
2364
|
-
partial: output
|
|
2365
|
-
});
|
|
2366
|
-
};
|
|
2367
|
-
const appendTextDeltaInternal = (text, source) => {
|
|
2368
|
-
if (currentBlock?.type === "text" && currentTextSource !== source) currentBlock = null;
|
|
2369
|
-
if (!currentBlock || currentBlock.type !== "text") {
|
|
2370
|
-
currentBlock = {
|
|
2371
|
-
type: "text",
|
|
2372
|
-
text: ""
|
|
2373
|
-
};
|
|
2374
|
-
currentTextSource = source;
|
|
2375
|
-
if (source === "reasoning_detail") (explicitVisibleTextBlocks ??= /* @__PURE__ */ new Set()).add(currentBlock);
|
|
2376
|
-
output.content.push(currentBlock);
|
|
2377
|
-
pushStreamEvent({
|
|
2378
|
-
type: "text_start",
|
|
2379
|
-
contentIndex: blockIndex(),
|
|
2380
|
-
partial: output
|
|
2381
|
-
});
|
|
2382
|
-
}
|
|
2383
|
-
currentBlock.text += text;
|
|
2384
|
-
if (pendingInterruptedTextBlock && text.trim()) {
|
|
2385
|
-
confirmedInterruptedTextBlock = pendingInterruptedTextBlock;
|
|
2386
|
-
pendingInterruptedTextBlock = null;
|
|
2387
|
-
}
|
|
2388
|
-
pushStreamEvent({
|
|
2389
|
-
type: "text_delta",
|
|
2390
|
-
contentIndex: blockIndex(),
|
|
2391
|
-
delta: text
|
|
2392
|
-
});
|
|
2393
|
-
};
|
|
2394
|
-
const flushPendingPostToolCallDeltas = () => {
|
|
2395
|
-
if (isFlushingPendingPostToolCallDeltas || currentBlock?.type === "toolCall" || pendingPostToolCallDeltas.length === 0) return;
|
|
2396
|
-
isFlushingPendingPostToolCallDeltas = true;
|
|
2397
|
-
const bufferedDeltas = pendingPostToolCallDeltas;
|
|
2398
|
-
pendingPostToolCallDeltas = [];
|
|
2399
|
-
pendingPostToolCallBytes = 0;
|
|
2400
|
-
for (const delta of bufferedDeltas) if (delta.kind === "text") appendTextDeltaInternal(delta.text, delta.source);
|
|
2401
|
-
else if (emitReasoning) appendThinkingDeltaInternal(delta);
|
|
2402
|
-
isFlushingPendingPostToolCallDeltas = false;
|
|
2403
|
-
};
|
|
2404
|
-
const appendThinkingDelta = (reasoningDelta) => {
|
|
2405
|
-
flushPendingPostToolCallDeltas();
|
|
2406
|
-
appendThinkingDeltaInternal(reasoningDelta);
|
|
2407
|
-
};
|
|
2408
|
-
const appendTextDelta = (text, source) => {
|
|
2409
|
-
flushPendingPostToolCallDeltas();
|
|
2410
|
-
appendTextDeltaInternal(text, source);
|
|
2411
|
-
};
|
|
2412
|
-
const appendVisibleTextDelta = (text) => {
|
|
2413
|
-
if (!text) return;
|
|
2414
|
-
if (currentBlock?.type === "toolCall") queuePostToolCallDelta({
|
|
2415
|
-
kind: "text",
|
|
2416
|
-
text
|
|
2417
|
-
});
|
|
2418
|
-
else appendTextDelta(text);
|
|
2419
|
-
};
|
|
2420
|
-
const appendReasoningDeltas = (reasoningDeltas) => {
|
|
2421
|
-
for (const reasoningDelta of reasoningDeltas) {
|
|
2422
|
-
if (reasoningDelta.kind === "thinking" && !emitReasoning) continue;
|
|
2423
|
-
if (currentBlock?.type === "toolCall") {
|
|
2424
|
-
queuePostToolCallDelta({ ...reasoningDelta });
|
|
2425
|
-
continue;
|
|
2426
|
-
}
|
|
2427
|
-
if (reasoningDelta.kind === "text") appendTextDelta(reasoningDelta.text, reasoningDelta.source);
|
|
2428
|
-
else if (emitReasoning) appendThinkingDelta(reasoningDelta);
|
|
2429
|
-
}
|
|
2430
|
-
};
|
|
2431
|
-
const appendRecoveredToolCall = (toolCall) => {
|
|
2432
|
-
if (currentBlock?.type === "toolCall") {
|
|
2433
|
-
currentBlock = null;
|
|
2434
|
-
flushPendingPostToolCallDeltas();
|
|
2435
|
-
}
|
|
2436
|
-
rememberPendingCommentaryTags(provisionalCommentaryTags, tagPendingCommentaryText(output.content));
|
|
2437
|
-
const block = {
|
|
2438
|
-
type: "toolCall",
|
|
2439
|
-
id: `call_${randomUUID().replaceAll("-", "").slice(0, 24)}`,
|
|
2440
|
-
name: toolCall.name,
|
|
2441
|
-
arguments: toolCall.arguments,
|
|
2442
|
-
partialArgs: toolCall.partialArgs
|
|
2443
|
-
};
|
|
2444
|
-
currentBlock = block;
|
|
2445
|
-
output.content.push(block);
|
|
2446
|
-
toolCallBlockIndices.set(block, output.content.length - 1);
|
|
2447
|
-
pushStreamEvent({
|
|
2448
|
-
type: "toolcall_start",
|
|
2449
|
-
contentIndex: toolCallBlockIndices.get(block) ?? -1,
|
|
2450
|
-
partial: output
|
|
2451
|
-
});
|
|
2452
|
-
pushStreamEvent({
|
|
2453
|
-
type: "toolcall_delta",
|
|
2454
|
-
contentIndex: toolCallBlockIndices.get(block) ?? -1,
|
|
2455
|
-
delta: toolCall.partialArgs,
|
|
2456
|
-
partial: output
|
|
2457
|
-
});
|
|
2458
|
-
};
|
|
2459
|
-
const appendFilteredVisibleTextDelta = (text) => {
|
|
2460
|
-
const recoveredParts = deepSeekToolCallRecoverer?.push(text) ?? [{
|
|
2461
|
-
kind: "text",
|
|
2462
|
-
text
|
|
2463
|
-
}];
|
|
2464
|
-
for (const recoveredPart of recoveredParts) {
|
|
2465
|
-
if (recoveredPart.kind === "toolCall") {
|
|
2466
|
-
appendRecoveredToolCall(recoveredPart);
|
|
2467
|
-
continue;
|
|
2468
|
-
}
|
|
2469
|
-
const parts = deepSeekTextFilter?.push(recoveredPart.text) ?? [recoveredPart.text];
|
|
2470
|
-
for (const part of parts) appendVisibleTextDelta(part);
|
|
2471
|
-
}
|
|
2472
|
-
};
|
|
2473
|
-
const flushDeepSeekToolCallRecovererAtEnd = () => {
|
|
2474
|
-
const recoveredParts = deepSeekToolCallRecoverer?.flush();
|
|
2475
|
-
if (!recoveredParts) return;
|
|
2476
|
-
for (const recoveredPart of recoveredParts) {
|
|
2477
|
-
if (recoveredPart.kind === "toolCall") {
|
|
2478
|
-
appendRecoveredToolCall(recoveredPart);
|
|
2479
|
-
continue;
|
|
2480
|
-
}
|
|
2481
|
-
const parts = deepSeekTextFilter?.push(recoveredPart.text) ?? [recoveredPart.text];
|
|
2482
|
-
for (const part of parts) appendVisibleTextDelta(part);
|
|
2483
|
-
}
|
|
2484
|
-
};
|
|
2485
|
-
const flushDeepSeekTextFilterAtEnd = () => {
|
|
2486
|
-
const parts = deepSeekTextFilter?.flush();
|
|
2487
|
-
if (!parts) return;
|
|
2488
|
-
for (const part of parts) appendVisibleTextDelta(part);
|
|
2489
|
-
};
|
|
2490
|
-
const appendRoutedContentDelta = (delta) => {
|
|
2491
|
-
if (delta.kind === "text") {
|
|
2492
|
-
appendFilteredVisibleTextDelta(delta.text);
|
|
2493
|
-
return;
|
|
2494
|
-
}
|
|
2495
|
-
if (!emitReasoning) return;
|
|
2496
|
-
if (currentBlock?.type === "toolCall") queuePostToolCallDelta(delta);
|
|
2497
|
-
else appendThinkingDelta(delta);
|
|
2498
|
-
};
|
|
2499
|
-
const appendPartitionedVisibleDelta = (delta) => {
|
|
2500
|
-
if (delta.kind === "text") appendFilteredVisibleTextDelta(delta.text);
|
|
2501
|
-
};
|
|
2502
|
-
const emitReasoningUsageActivity = (hasReasoningUsageActivity) => {
|
|
2503
|
-
if (!hasReasoningUsageActivity || chunkPushedEvent || !emitReasoning) return;
|
|
2504
|
-
const latestBlock = output.content[output.content.length - 1];
|
|
2505
|
-
if (currentBlock?.type === "text" || currentBlock?.type === "toolCall") return;
|
|
2506
|
-
if (latestBlock?.type === "text" || latestBlock?.type === "toolCall") return;
|
|
2507
|
-
appendThinkingDelta({ text: "" });
|
|
2508
|
-
};
|
|
2509
|
-
const flushReasoningTagTextPartitioner = () => {
|
|
2510
|
-
for (const delta of reasoningTagTextPartitioner.flush()) appendPartitionedVisibleDelta(delta);
|
|
2511
|
-
};
|
|
2512
|
-
const sealTextBeforeReasoning = () => {
|
|
2513
|
-
if (currentBlock?.type !== "text" && !reasoningTagTextPartitioner.hasPending()) return;
|
|
2514
|
-
flushReasoningTagTextPartitioner();
|
|
2515
|
-
if (currentBlock?.type !== "text") return;
|
|
2516
|
-
if (currentTextSource !== "reasoning_detail" && currentBlock.text.trim()) pendingInterruptedTextBlock = currentBlock;
|
|
2517
|
-
currentBlock = null;
|
|
2518
|
-
currentTextSource = void 0;
|
|
2519
|
-
};
|
|
2520
|
-
const beginReasoning = (hasFollowingVisibleText, forceStrict = false) => {
|
|
2521
|
-
if (!output.openclawDelivery?.textPhaseRequiresTerminal) output.openclawDelivery = {
|
|
2522
|
-
...output.openclawDelivery,
|
|
2523
|
-
textPhaseRequiresTerminal: true
|
|
2524
|
-
};
|
|
2525
|
-
if (forceStrict || reasoningTagTextPartitioner.hasPending()) reasoningTagTextPartitioner.markStrict();
|
|
2526
|
-
if (!hasFollowingVisibleText || !reasoningTagTextPartitioner.hasPendingSyntax()) sealTextBeforeReasoning();
|
|
2527
|
-
};
|
|
2528
|
-
const cooperativeScheduler = createModelStreamCooperativeScheduler(options?.signal);
|
|
2529
|
-
const guardedStream = withFirstStreamEventTimeout(responseStream, {
|
|
2530
|
-
provider: model.provider,
|
|
2531
|
-
api: model.api,
|
|
2532
|
-
model: model.id,
|
|
2533
|
-
timeoutMs: options?.firstEventTimeoutMs ?? 0,
|
|
2534
|
-
stage: "completions",
|
|
2535
|
-
abort: options?.abortFirstEventStream,
|
|
2536
|
-
onTimeout: options?.onFirstEventTimeout,
|
|
2537
|
-
hint: "The provider may be stalled while parsing the tool payload; retry with a smaller tool surface or enable OPENCLAW_DEBUG_MODEL_PAYLOAD=tools to inspect exposed tools."
|
|
2538
|
-
});
|
|
2539
|
-
for await (const rawChunk of guardedStream) {
|
|
2540
|
-
throwIfModelStreamAborted(options?.signal);
|
|
2541
|
-
chunkPushedEvent = false;
|
|
2542
|
-
if (!rawChunk || typeof rawChunk !== "object") {
|
|
2543
|
-
await cooperativeScheduler.afterEvent();
|
|
2544
|
-
continue;
|
|
2545
|
-
}
|
|
2546
|
-
notifyLlmRequestActivity(options?.signal);
|
|
2547
|
-
const chunk = rawChunk;
|
|
2548
|
-
output.responseId ||= chunk.id;
|
|
2549
|
-
let hasReasoningUsageActivity = false;
|
|
2550
|
-
if (chunk.usage) {
|
|
2551
|
-
output.usage = parseOpenAICompletionsUsage(chunk.usage, model);
|
|
2552
|
-
hasReasoningUsageActivity = hasOpenAICompletionsReasoningUsageActivity(chunk.usage);
|
|
2553
|
-
}
|
|
2554
|
-
const choice = Array.isArray(chunk.choices) ? chunk.choices[0] : void 0;
|
|
2555
|
-
if (!choice) {
|
|
2556
|
-
emitReasoningUsageActivity(hasReasoningUsageActivity);
|
|
2557
|
-
await cooperativeScheduler.afterEvent();
|
|
2558
|
-
continue;
|
|
2559
|
-
}
|
|
2560
|
-
const choiceUsage = choice.usage;
|
|
2561
|
-
if (!chunk.usage && choiceUsage) {
|
|
2562
|
-
output.usage = parseOpenAICompletionsUsage(choiceUsage, model);
|
|
2563
|
-
hasReasoningUsageActivity = hasOpenAICompletionsReasoningUsageActivity(choiceUsage);
|
|
2564
|
-
}
|
|
2565
|
-
if (choice.finish_reason) {
|
|
2566
|
-
const finishReasonResult = mapOpenAIStopReason(choice.finish_reason, { allowSingularToolCall: true });
|
|
2567
|
-
output.stopReason = finishReasonResult.stopReason;
|
|
2568
|
-
if (finishReasonResult.stopReason === "stop") sawStopFinishReason = true;
|
|
2569
|
-
if (finishReasonResult.errorMessage) output.errorMessage = finishReasonResult.errorMessage;
|
|
2570
|
-
}
|
|
2571
|
-
const rawChoiceDelta = choice.delta ?? choice.message;
|
|
2572
|
-
if (!rawChoiceDelta) {
|
|
2573
|
-
emitReasoningUsageActivity(hasReasoningUsageActivity);
|
|
2574
|
-
await cooperativeScheduler.afterEvent();
|
|
2575
|
-
continue;
|
|
2576
|
-
}
|
|
2577
|
-
for (const normalizedDelta of normalizeToolCallDeltas(rawChoiceDelta, choice.finish_reason)) {
|
|
2578
|
-
const choiceDelta = normalizedDelta.delta;
|
|
2579
|
-
const reasoningBatch = readOpenAICompletionsReasoningBatch(choiceDelta, visibleReasoningDetailTypes);
|
|
2580
|
-
const reasoningDeltas = reasoningBatch.deltas;
|
|
2581
|
-
const hasReasoningThinking = reasoningBatch.hasThinking;
|
|
2582
|
-
const contentDeltas = readOpenAICompletionsContentDeltas(choiceDelta.content, choiceDelta.refusal, reasoningBatch.mirroredThinking);
|
|
2583
|
-
const lastVisibleTextIndex = contentDeltas.findLastIndex((delta) => delta.kind === "text");
|
|
2584
|
-
const hasSameChunkVisibleText = reasoningBatch.hasVisibleText || lastVisibleTextIndex !== -1;
|
|
2585
|
-
if (hasReasoningThinking) {
|
|
2586
|
-
beginReasoning(hasSameChunkVisibleText, true);
|
|
2587
|
-
appendReasoningDeltas(reasoningDeltas);
|
|
2588
|
-
}
|
|
2589
|
-
for (const [contentDeltaIndex, contentDelta] of contentDeltas.entries()) if (contentDelta.kind === "text") {
|
|
2590
|
-
const routedDeltas = hasReasoningThinking ? reasoningTagTextPartitioner.push(contentDelta.text) : reasoningTagTextPartitioner.pushVisible(contentDelta.text);
|
|
2591
|
-
for (const routedDelta of routedDeltas) appendPartitionedVisibleDelta(routedDelta);
|
|
2592
|
-
} else {
|
|
2593
|
-
beginReasoning(contentDeltaIndex < lastVisibleTextIndex);
|
|
2594
|
-
appendRoutedContentDelta(contentDelta);
|
|
2595
|
-
}
|
|
2596
|
-
if (!hasReasoningThinking) appendReasoningDeltas(reasoningDeltas);
|
|
2597
|
-
const toolCallDeltas = normalizedDelta.toolCalls;
|
|
2598
|
-
if (toolCallDeltas.length > 0) {
|
|
2599
|
-
sawNativeToolCallDelta = true;
|
|
2600
|
-
flushReasoningTagTextPartitioner();
|
|
2601
|
-
rememberPendingCommentaryTags(provisionalCommentaryTags, tagPendingCommentaryText(output.content));
|
|
2602
|
-
for (const toolCall of toolCallDeltas) {
|
|
2603
|
-
const streamIndex = typeof toolCall.index === "number" ? toolCall.index : void 0;
|
|
2604
|
-
let block = streamIndex !== void 0 ? toolCallBlocksByIndex.get(streamIndex) : void 0;
|
|
2605
|
-
if (!block && toolCall.id) block = toolCallBlocksById.get(toolCall.id);
|
|
2606
|
-
if (!block) {
|
|
2607
|
-
if (currentBlock?.type === "toolCall") {
|
|
2608
|
-
currentBlock = null;
|
|
2609
|
-
flushPendingPostToolCallDeltas();
|
|
2610
|
-
}
|
|
2611
|
-
const initialSig = extractToolCallThoughtSignature(toolCall);
|
|
2612
|
-
block = {
|
|
2613
|
-
type: "toolCall",
|
|
2614
|
-
id: toolCall.id || "",
|
|
2615
|
-
name: toolCall.function?.name || "",
|
|
2616
|
-
arguments: {},
|
|
2617
|
-
partialArgs: "",
|
|
2618
|
-
...initialSig ? { thoughtSignature: initialSig } : {}
|
|
2619
|
-
};
|
|
2620
|
-
output.content.push(block);
|
|
2621
|
-
toolCallBlockIndices.set(block, output.content.length - 1);
|
|
2622
|
-
pushStreamEvent({
|
|
2623
|
-
type: "toolcall_start",
|
|
2624
|
-
contentIndex: toolCallBlockIndices.get(block) ?? -1,
|
|
2625
|
-
partial: output
|
|
2626
|
-
});
|
|
2627
|
-
}
|
|
2628
|
-
if (streamIndex !== void 0 && !toolCallBlocksByIndex.has(streamIndex)) toolCallBlocksByIndex.set(streamIndex, block);
|
|
2629
|
-
if (toolCall.id) {
|
|
2630
|
-
block.id = toolCall.id;
|
|
2631
|
-
toolCallBlocksById.set(toolCall.id, block);
|
|
2632
|
-
}
|
|
2633
|
-
currentBlock = block;
|
|
2634
|
-
if (toolCall.function?.name) block.name = toolCall.function.name;
|
|
2635
|
-
const deltaSig = extractToolCallThoughtSignature(toolCall);
|
|
2636
|
-
if (deltaSig) block.thoughtSignature = deltaSig;
|
|
2637
|
-
if (toolCall.function?.arguments) {
|
|
2638
|
-
block.partialArgs += toolCall.function.arguments;
|
|
2639
|
-
block.arguments = parseStreamingJson(block.partialArgs);
|
|
2640
|
-
pushStreamEvent({
|
|
2641
|
-
type: "toolcall_delta",
|
|
2642
|
-
contentIndex: toolCallBlockIndices.get(block) ?? -1,
|
|
2643
|
-
delta: toolCall.function.arguments,
|
|
2644
|
-
partial: output
|
|
2645
|
-
});
|
|
2646
|
-
}
|
|
2647
|
-
}
|
|
2648
|
-
}
|
|
2649
|
-
}
|
|
2650
|
-
flushPendingPostToolCallDeltas();
|
|
2651
|
-
emitReasoningUsageActivity(hasReasoningUsageActivity);
|
|
2652
|
-
await cooperativeScheduler.afterEvent();
|
|
2653
|
-
}
|
|
2654
|
-
flushReasoningTagTextPartitioner();
|
|
2655
|
-
flushDeepSeekToolCallRecovererAtEnd();
|
|
2656
|
-
flushDeepSeekTextFilterAtEnd();
|
|
2657
|
-
currentBlock = null;
|
|
2658
|
-
flushPendingPostToolCallDeltas();
|
|
2659
|
-
finalizeOpenAICompletionsToolCalls(output, {
|
|
2660
|
-
allowSilentToolCallPromotion: sawStopFinishReason || sawNativeToolCallDelta && (options?.sawStreamDONE?.() ?? false),
|
|
2661
|
-
onConfirmedToolCall(block, contentIndex) {
|
|
2662
|
-
if (block.type !== "toolCall") return;
|
|
2663
|
-
pushStreamEvent({
|
|
2664
|
-
type: "toolcall_end",
|
|
2665
|
-
contentIndex,
|
|
2666
|
-
toolCall: block,
|
|
2667
|
-
partial: output
|
|
2668
|
-
});
|
|
2669
|
-
}
|
|
2670
|
-
});
|
|
2671
|
-
if (confirmedInterruptedTextBlock && output.stopReason !== "toolUse" && output.stopReason !== "error" && output.stopReason !== "aborted") tagInterruptedTextPhases(output.content, confirmedInterruptedTextBlock, explicitVisibleTextBlocks);
|
|
2672
|
-
if (output.stopReason !== "toolUse") clearPendingCommentaryText(provisionalCommentaryTags);
|
|
2673
|
-
if (output.stopReason === "error" || output.stopReason === "aborted") tagUnresolvedTextAsCommentary(output);
|
|
2674
|
-
if (output.stopReason === "toolUse") tagPendingCommentaryText(output.content);
|
|
2675
|
-
}
|
|
2676
|
-
function resolveOpenAICompletionsReasoningEffort(options) {
|
|
2677
|
-
return options?.reasoningEffort ?? options?.reasoning ?? "high";
|
|
2678
|
-
}
|
|
2679
|
-
function shouldEmitOpenAICompletionsReasoning(model, options) {
|
|
2680
|
-
if (!model.reasoning) return false;
|
|
2681
|
-
const effort = resolveOpenAICompletionsReasoningEffort(options);
|
|
2682
|
-
if (!effort || !isOpenAICompletionsThinkingEnabled(effort)) return false;
|
|
2683
|
-
return true;
|
|
2684
|
-
}
|
|
2685
|
-
function hasOpenAICompletionsReasoningUsageActivity(rawUsage) {
|
|
2686
|
-
const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens;
|
|
2687
|
-
return typeof reasoningTokens === "number" && Number.isFinite(reasoningTokens) && reasoningTokens > 0;
|
|
2688
|
-
}
|
|
2689
|
-
//#endregion
|
|
2690
1691
|
//#region packages/ai/src/transports/openai-completions-transport.ts
|
|
2691
1692
|
function assertOpenAICompletionsPayloadHasConversationTurn(params, model) {
|
|
2692
1693
|
const messages = params.messages;
|
|
@@ -2762,7 +1763,7 @@ function buildOpenAICompletionsClientConfig(model, context, optionHeaders) {
|
|
|
2762
1763
|
}
|
|
2763
1764
|
}
|
|
2764
1765
|
return {
|
|
2765
|
-
baseURL,
|
|
1766
|
+
baseURL: resolveOpenAIClientBaseUrl(model, baseURL),
|
|
2766
1767
|
defaultHeaders: headers,
|
|
2767
1768
|
defaultQuery: Object.keys(defaultQuery).length > 0 ? defaultQuery : void 0
|
|
2768
1769
|
};
|
|
@@ -3650,7 +2651,7 @@ function resolveProviderTransportTurnState(model, params) {
|
|
|
3650
2651
|
function createOpenAIResponsesClient(model, context, apiKey, optionHeaders, turnHeaders, sessionId) {
|
|
3651
2652
|
return new OpenAI({
|
|
3652
2653
|
apiKey,
|
|
3653
|
-
baseURL: model
|
|
2654
|
+
baseURL: resolveOpenAIClientBaseUrl(model),
|
|
3654
2655
|
dangerouslyAllowBrowser: true,
|
|
3655
2656
|
defaultHeaders: buildOpenAIClientHeaders(model, context, optionHeaders, turnHeaders, sessionId),
|
|
3656
2657
|
fetch: buildGuardedModelFetch(model),
|
|
@@ -3778,7 +2779,7 @@ function createResponsesTransportExecutor(config) {
|
|
|
3778
2779
|
emitModelTransportDebug(log, `[responses] start provider=${model.provider} api=${model.api} model=${model.id} requestIdHash=${redactIdentifier(options?.requestId, { len: 64 })} baseUrl=${formatModelTransportDebugBaseUrl(model.baseUrl)} timeoutMs=${safeDebugValue(requestOptions?.timeout)} apiKey=${apiKey ? "present" : "missing"} ${summarizeResponsesPayload(params)}`);
|
|
3779
2780
|
let continuationBaseline;
|
|
3780
2781
|
const createSseStream = async (initialRequest = continuationClaim?.request ?? params, initialAttemptKind = "initial", initialRejectedCompaction) => {
|
|
3781
|
-
const { stream:
|
|
2782
|
+
const { stream: responseStream } = await config.createResponseStream({
|
|
3782
2783
|
client,
|
|
3783
2784
|
request: initialRequest,
|
|
3784
2785
|
requestOptions,
|
|
@@ -3787,19 +2788,23 @@ function createResponsesTransportExecutor(config) {
|
|
|
3787
2788
|
initialAttemptKind,
|
|
3788
2789
|
initialRejectedCompaction,
|
|
3789
2790
|
buildFullHistoryRequest: () => buildRequest("full-history"),
|
|
3790
|
-
onCompactionRejected: (checkpoint) => suppressOpenAIResponsesCompaction(output, model, responsesOptions, checkpoint)
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
2791
|
+
onCompactionRejected: (checkpoint) => suppressOpenAIResponsesCompaction(output, model, responsesOptions, checkpoint),
|
|
2792
|
+
canRetryStream: () => output.content.length === 0,
|
|
2793
|
+
wrapStream: ({ stream: rawResponseStream, response, attempt }) => {
|
|
2794
|
+
if (continuationClaim) continuationBaseline = attempt.request.previous_response_id ? params : attempt.request;
|
|
2795
|
+
return withProviderResponseHook({
|
|
2796
|
+
stream: observeResponsesStream(rawResponseStream, model, requestStartedAt),
|
|
2797
|
+
signal: firstEvent.signal,
|
|
2798
|
+
abort: firstEvent.abort,
|
|
2799
|
+
hook: createOpenAIProviderAcceptanceHook(options, response, model),
|
|
2800
|
+
onReady: () => {
|
|
2801
|
+
emitModelTransportDebug(log, `[responses] headers provider=${model.provider} api=${model.api} model=${model.id} transport=sse elapsedMs=${Date.now() - requestStartedAt}`);
|
|
2802
|
+
startStream();
|
|
2803
|
+
}
|
|
2804
|
+
});
|
|
3801
2805
|
}
|
|
3802
2806
|
});
|
|
2807
|
+
return responseStream;
|
|
3803
2808
|
};
|
|
3804
2809
|
let responseStream;
|
|
3805
2810
|
let finishWebSocket;
|
|
@@ -4301,4 +3306,4 @@ function prepareModelForSimpleCompletion(params) {
|
|
|
4301
3306
|
return applyProviderSimpleCompletionWrapper(apiRegistry, model, cfg);
|
|
4302
3307
|
}
|
|
4303
3308
|
//#endregion
|
|
4304
|
-
export { GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, applyAnthropicCacheControlToMessages, applyAnthropicEphemeralCacheControlMarkers, applyAnthropicPayloadPolicyToParams, applyOpenAIResponsesPayloadPolicy, assertCodeModeResponsesToolSurface, assignTransportErrorDetails, buildOpenAIClientHeaders, buildOpenAICompletionsParams, buildOpenAISdkClientOptions, buildOpenAISdkRequestOptions, buildTransportAwareSimpleStreamFn, canonicalizeMaxTokensParam, captureOpenAIResponsesCompaction, coerceTransportToolCallArguments, copyProviderAcceptanceObserver, createAnthropicMessagesTransportStreamFn, createAzureOpenAIResponsesTransportStreamFn, createBoundaryAwareStreamFnForModel, createDeepSeekTextFilter, createEmptyTransportUsage, createModelStreamCooperativeScheduler, createOpenAICompletionsTransportStreamFn, createOpenAIProviderAcceptanceHook, createOpenAIResponseHook, createOpenAIResponsesTransportStreamFn, createOpenClawTransportStreamFnForModel, createTransportAwareStreamFnForModel, createWritableTransportEventStream, detectOpenAICompletionsCompat, emitModelTransportDebug, enforceCodeModeResponsesToolSurface, failTransportStream, filterCodeModePayloadTools, finalizeTerminalToolCallArguments, finalizeTransportStream, flattenCompletionMessagesToStringContent, formatModelTransportDebugBaseUrl, formatModelTransportDebugUrl, getCompat, googleFlashSupportsMinimalThinking, hasOpenAICompatibleConversationTurn, isCodeModeModelVisibleToolName, isCompactionReplayCheckpoint, isOpenAICodexResponsesModel, isOpenAICompletionsThinkingEnabled, log, measureUtf8AppendBytes, mergeTransportHeaders, mergeTransportMetadata, normalizeCodexResponsesBaseUrlForOpenAISdk, notifyProviderHttpMetadata, notifyProviderHttpResponse, notifyProviderStreamOpened, parseJsonObjectPreservingUnsafeIntegers, parseJsonPreservingUnsafeIntegers, parseOpenAICompletionsUsage, parseTerminalToolCallArguments, prepareModelForSimpleCompletion, prepareTransportAwareSimpleModel, quoteUnsafeIntegerLiterals, readCodeModePayloadToolName, readOpenAICompletionsContentDeltas, readOpenAICompletionsReasoningBatch, replaceCompactionReplayOwnerContent, requestPreparedOpenAIResponsesCompaction, resolveAnthropicEphemeralCacheControl, resolveAnthropicMessagesUrl, resolveAnthropicPayloadPolicy, resolveAnthropicServerCompactionPlan, resolveCodeModeResponsesVisibleToolNames, resolveMaxTokensParam, resolveModelPayloadDebugMode, resolveModelSseDebugMode, resolveOpenAICompletionsCompat, resolveOpenAIReasoningEffortMap, resolveOpenAIResponsesCompactEndpointPlan, resolveOpenAIResponsesPayloadPolicy, resolveOpenAIResponsesServerCompactionPlan, resolveOpenAIStrictToolFlagWithDiagnostics, resolvePromptCacheKey, resolveReplayableResponsesMessageId, resolveTransportAwareSimpleApi, sanitizeNonEmptyTransportPayloadText, sanitizeResponsesImagePayload, sanitizeTransportPayloadText, sortPromptCacheToolsByName as sortTransportToolsByName, stripCompactionReplayCheckpoint, stripCompactionReplayCheckpointInPlace, stripCompletionMessagesToRoleContent, throwIfModelStreamAborted, transportAbortError, usesNativeOpenAICodexResponsesBackend, withProviderAcceptanceObserver, withProviderResponseHook };
|
|
3309
|
+
export { GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, applyAnthropicCacheControlToMessages, applyAnthropicEphemeralCacheControlMarkers, applyAnthropicPayloadPolicyToParams, applyOpenAIResponsesPayloadPolicy, assertCodeModeResponsesToolSurface, assignTransportErrorDetails, buildOpenAIClientHeaders, buildOpenAICompletionsParams, buildOpenAISdkClientOptions, buildOpenAISdkRequestOptions, buildTransportAwareSimpleStreamFn, canonicalizeMaxTokensParam, captureOpenAIResponsesCompaction, coerceTransportToolCallArguments, copyProviderAcceptanceObserver, createAnthropicMessagesTransportStreamFn, createAzureOpenAIResponsesTransportStreamFn, createBoundaryAwareStreamFnForModel, createDeepSeekTextFilter, createEmptyTransportUsage, createModelStreamCooperativeScheduler, createOpenAICompletionsTransportStreamFn, createOpenAIProviderAcceptanceHook, createOpenAIResponseHook, createOpenAIResponsesTransportStreamFn, createOpenClawTransportStreamFnForModel, createTransportAwareStreamFnForModel, createWritableTransportEventStream, detectOpenAICompletionsCompat, emitModelTransportDebug, enforceCodeModeResponsesToolSurface, failTransportStream, filterCodeModePayloadTools, finalizeTerminalToolCallArguments, finalizeTransportStream, flattenCompletionMessagesToStringContent, formatModelTransportDebugBaseUrl, formatModelTransportDebugUrl, getCompat, googleFlashSupportsMinimalThinking, hasOpenAICompatibleConversationTurn, isCodeModeModelVisibleToolName, isCompactionReplayCheckpoint, isOpenAICodexResponsesModel, isOpenAICompletionsThinkingEnabled, log, measureUtf8AppendBytes, mergeTransportHeaders, mergeTransportMetadata, normalizeCodexResponsesBaseUrlForOpenAISdk, notifyProviderHttpMetadata, notifyProviderHttpResponse, notifyProviderStreamOpened, parseJsonObjectPreservingUnsafeIntegers, parseJsonPreservingUnsafeIntegers, parseOpenAICompletionsUsage, parseTerminalToolCallArguments, prepareModelForSimpleCompletion, prepareTransportAwareSimpleModel, quoteUnsafeIntegerLiterals, readCodeModePayloadToolName, readOpenAICompletionsContentDeltas, readOpenAICompletionsReasoningBatch, replaceCompactionReplayOwnerContent, requestPreparedOpenAIResponsesCompaction, resolveAnthropicEphemeralCacheControl, resolveAnthropicMessagesUrl, resolveAnthropicPayloadPolicy, resolveAnthropicServerCompactionPlan, resolveCodeModeResponsesVisibleToolNames, resolveMaxTokensParam, resolveModelPayloadDebugMode, resolveModelSseDebugMode, resolveOpenAIClientBaseUrl, resolveOpenAICompletionsCompat, resolveOpenAIReasoningEffortMap, resolveOpenAIResponsesCompactEndpointPlan, resolveOpenAIResponsesPayloadPolicy, resolveOpenAIResponsesServerCompactionPlan, resolveOpenAIStrictToolFlagWithDiagnostics, resolvePromptCacheKey, resolveReplayableResponsesMessageId, resolveTransportAwareSimpleApi, sanitizeNonEmptyTransportPayloadText, sanitizeResponsesImagePayload, sanitizeTransportPayloadText, sortPromptCacheToolsByName as sortTransportToolsByName, stripCompactionReplayCheckpoint, stripCompactionReplayCheckpointInPlace, stripCompletionMessagesToRoleContent, throwIfModelStreamAborted, transportAbortError, usesNativeOpenAICodexResponsesBackend, withProviderAcceptanceObserver, withProviderResponseHook };
|