@openclaw/ai 2026.7.2-beta.7 → 2026.8.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.
Files changed (57) hide show
  1. package/dist/{anthropic-CH4UUnZr.mjs → anthropic-CE-7SkF6.mjs} +28 -191
  2. package/dist/{anthropic-usage-DWU-x8MI.mjs → anthropic-usage-Ma4iX6uG.mjs} +262 -4
  3. package/dist/{api-registry-DlMgPR39.d.mts → api-registry-EpJoVwM1.d.mts} +1 -1
  4. package/dist/{azure-openai-responses-CImcwB83.mjs → azure-openai-responses-Cc_kasye.mjs} +4 -4
  5. package/dist/{event-stream-D8n2uFee.mjs → event-stream-CEV9t6da.mjs} +10 -2
  6. package/dist/{event-stream-YjaPW20U.d.mts → event-stream-DRmDMRHH.d.mts} +2 -1
  7. package/dist/event-stream.d.mts +1 -1
  8. package/dist/event-stream.mjs +1 -1
  9. package/dist/{google-CtSg0iTS.mjs → google-CGQu21aw.mjs} +5 -5
  10. package/dist/{google-shared-DNBz5rcD.mjs → google-shared-Cq2UKx1l.mjs} +151 -85
  11. package/dist/{google-vertex-31f1uS9L.mjs → google-vertex-CusxWzvE.mjs} +10 -7
  12. package/dist/{host-Dog2WQiR.mjs → host-Bl7Kgddo.mjs} +40 -2
  13. package/dist/{host-B9GUmcra.d.mts → host-Dn4_SZI2.d.mts} +2 -2
  14. package/dist/index.d.mts +5 -5
  15. package/dist/index.mjs +2 -2
  16. package/dist/internal/anthropic.d.mts +19 -3
  17. package/dist/internal/anthropic.mjs +4 -4
  18. package/dist/internal/openai.d.mts +4 -4
  19. package/dist/internal/openai.mjs +7 -7
  20. package/dist/internal/runtime.d.mts +2 -2
  21. package/dist/internal/runtime.mjs +3 -3
  22. package/dist/internal/shared.d.mts +1 -1
  23. package/dist/internal/shared.mjs +3 -4
  24. package/dist/{mistral-CWmpvWYh.mjs → mistral-Dx6VzNjf.mjs} +25 -9
  25. package/dist/model-utils-Dau5dlgm.mjs +64 -0
  26. package/dist/number-coercion-1Miyb5MO.mjs +66 -0
  27. package/dist/{openai-chatgpt-responses-B84Ibtrd.mjs → openai-chatgpt-responses-SC9m0FSf.mjs} +94 -131
  28. package/dist/{openai-completions-DsOxhOD1.mjs → openai-completions-BaIpl93j.mjs} +47 -66
  29. package/dist/{openai-reasoning-compat-YgeLncHw.mjs → openai-reasoning-compat-DKebnIBL.mjs} +147 -6
  30. package/dist/{openai-responses-BT7A3sLu.mjs → openai-responses-Bdx3V_Yu.mjs} +6 -22
  31. package/dist/openai-responses-contracts-BBKBfAqR.d.mts +116 -0
  32. package/dist/openai-responses-prompt-observer-internal-DDZPxRfr.mjs +46 -0
  33. package/dist/{openai-responses-shared-pXl6Wd8S.mjs → openai-responses-shared-CCyMvg7M.mjs} +21 -10
  34. package/dist/{openai-responses-stream-internal-Cw5txaGW.mjs → openai-responses-stream-internal-Bl8YyVtF.mjs} +244 -81
  35. package/dist/{openai-tool-projection-OhX64DoP.mjs → openai-transport-shared-Cipt7egQ.mjs} +129 -29
  36. package/dist/{provider-error-CAEvRjry.mjs → provider-error-DI0Ts28U.mjs} +1 -1
  37. package/dist/{provider-options-D8bB3z9b.d.mts → provider-options-C5kYML7i.d.mts} +1 -1
  38. package/dist/providers.d.mts +1 -1
  39. package/dist/providers.mjs +9 -9
  40. package/dist/{stream-first-event-timeout-BBys9hSb.mjs → stream-first-event-timeout-BIBomOGq.mjs} +1 -1
  41. package/dist/{tool-result-text-CTpIRbYd.mjs → tool-result-text-Dvkp2Dus.mjs} +51 -2
  42. package/dist/{tool-schema-json-projection-BwNu3nDi.mjs → tool-schema-json-projection-B1b-XCn5.mjs} +28 -1
  43. package/dist/transform-messages-DfjpNXNQ.mjs +2 -0
  44. package/dist/{transport-stream-shared-D81p90xq.mjs → transport-stream-shared-CPNv7A3r.mjs} +4 -4
  45. package/dist/transports.d.mts +41 -73
  46. package/dist/transports.mjs +317 -601
  47. package/dist/{types-bzp5k29J.d.mts → types-CH7ReIcU.d.mts} +4 -0
  48. package/dist/types.d.mts +3 -3
  49. package/dist/types.mjs +1 -1
  50. package/dist/{validation-B-j7cOYp.d.mts → validation-CcPcuEbR.d.mts} +1 -1
  51. package/dist/validation.d.mts +1 -1
  52. package/package.json +1 -1
  53. package/dist/error-coercion-DgxlWC0n.mjs +0 -15
  54. package/dist/number-coercion-DvG7SNMg.mjs +0 -129
  55. package/dist/openai-completions-compat-DBWjXoMZ.d.mts +0 -43
  56. package/dist/simple-options-9lhRrN73.mjs +0 -50
  57. package/dist/transform-messages-C8mBqZxF.mjs +0 -2
@@ -1,364 +1,45 @@
1
1
  import { n as getEnvApiKey } from "./env-api-keys-DrgeBuva.mjs";
2
- import { d as resolveClaudeSonnet5ModelIdentity, g as supportsClaudeNativeXhighEffort, h as supportsClaudeNativeMaxEffort, l as resolveClaudeNativeThinkingLevelMap, p as supportsClaudeAdaptiveThinking, u as resolveClaudeOpus5ModelIdentity } from "./src-QkygScBs.mjs";
3
- import { r as createAssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
4
- import { a as applyClaudeRequestContract, c as requiresClaudeAdaptiveThinking, d as usesClaudeStreamingRefusalContract, f as hasNonEmptyString, g as isRecord, h as readStringValue, n as getAiTransportHost, o as defaultsClaudeAdaptiveThinking, p as normalizeLowercaseStringOrEmpty, r as resolveAiTransportHeaderSentinels, s as prepareClaudeNoPrefillRequestContext, u as usesClaudeFable5MessagesContract } from "./host-Dog2WQiR.mjs";
2
+ import { d as resolveClaudeSonnet5ModelIdentity, g as supportsClaudeNativeXhighEffort, p as supportsClaudeAdaptiveThinking, u as resolveClaudeOpus5ModelIdentity } from "./src-QkygScBs.mjs";
3
+ import { r as createAssistantMessageEventStream } from "./event-stream-CEV9t6da.mjs";
4
+ import { _ as normalizeLowercaseStringOrEmpty, a as ANTHROPIC_CLAUDE_CODE_BILLING_SYSTEM_BLOCK, b as isRecord, c as defaultsClaudeAdaptiveThinking, d as requiresClaudeAdaptiveThinking, f as resolveAnthropicThinkingEffort, g as hasNonEmptyString, h as usesClaudeStreamingRefusalContract, l as mapAnthropicStopReason, m as usesClaudeFable5MessagesContract, n as getAiTransportHost, o as ANTHROPIC_CLAUDE_CODE_VERSION, r as resolveAiTransportHeaderSentinels, s as applyClaudeRequestContract, u as prepareClaudeNoPrefillRequestContext, y as readStringValue } from "./host-Bl7Kgddo.mjs";
5
+ import { n as calculateCost } from "./model-utils-Dau5dlgm.mjs";
5
6
  import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-mZTCdRPo.mjs";
6
7
  import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
7
- import { a as isImageWithMediaPayload, d as stripSystemPromptCacheBoundary, m as sortPromptCacheToolsByName, n as extractToolResultBlockText, r as extractToolResultText, t as describeToolResultMediaPlaceholder, u as splitSystemPromptCacheBoundary } from "./tool-result-text-CTpIRbYd.mjs";
8
- import { a as resolveModelRequestTimeoutMs, c as resolveProviderRequestCapabilities, i as buildGuardedModelFetch, l as resolveProviderRequestPolicyConfig, n as reconcileOpenAICompletionsToolChoice, o as resolveOpenAIStrictToolSetting, r as reconcileOpenAIResponsesToolChoice, s as resolveProviderEndpoint, t as projectOpenAITools, u as transformTransportMessages } from "./openai-tool-projection-OhX64DoP.mjs";
9
- import { t as toErrorObject } from "./error-coercion-DgxlWC0n.mjs";
10
- import { S as canonicalizeBase64, _ as omitFoundryBearerCredentialHeaders, a as projectAnthropicTools, b as normalizeAnthropicInlineContent, c as ANTHROPIC_OMITTED_REASONING_TEXT, d as ANTHROPIC_SERVER_SIDE_FALLBACK_BETA, g as applyAnthropicRefusal, h as resolveAnthropicFallbackServingModelCost, i as readLastAnthropicIterationUsage, l as findActiveAnthropicToolTurnAssistantIndex, m as readAnthropicFallbackBoundary, n as readAnthropicPromptUsageSnapshot, o as reconcileAnthropicToolChoice, p as applyAnthropicFallbackBoundary, r as readAnthropicUsageTokenCount, s as resolveOriginalAnthropicToolName, u as ANTHROPIC_SERVER_SIDE_FALLBACKS, v as usesFoundryBearerAuth, x as resolveAnthropicImageMediaType, y as createAnthropicInlineImageBudget } from "./anthropic-usage-DWU-x8MI.mjs";
11
- import { a as parseStrictPositiveInteger, c as calculateCost, l as clampThinkingLevel, s as applyProviderReportedUsageCost } from "./number-coercion-DvG7SNMg.mjs";
12
- import { a as resolveOpenAICompletionsCompat, c as clearPendingCommentaryText, i as detectOpenAICompletionsCompat, l as rememberPendingCommentaryTags, n as mapOpenAIStopReason, o as resolveOpenAICompletionsResponseFormat, r as convertMessages, s as shouldOmitOllamaCompatResponseFormat, t as resolveOpenAIReasoningEffortMap, u as tagPendingCommentaryText } from "./openai-reasoning-compat-YgeLncHw.mjs";
8
+ import { a as isImageWithMediaPayload, h as stripSystemPromptCacheBoundary, n as extractToolResultBlockText, r as extractToolResultText, s as adjustMaxTokensForThinking, t as describeToolResultMediaPlaceholder, v as sortPromptCacheToolsByName } from "./tool-result-text-Dvkp2Dus.mjs";
9
+ import { a as resolveProviderEndpoint, c as transformTransportMessages, i as resolveOpenAIStrictToolSetting, n as buildGuardedModelFetch, r as resolveModelRequestTimeoutMs, s as resolveProviderRequestPolicyConfig } from "./tool-schema-json-projection-B1b-XCn5.mjs";
10
+ import { A as applyAnthropicPayloadPolicyToParams, C as usesFoundryBearerAuth, D as canonicalizeBase64, E as resolveAnthropicImageMediaType, M as resolveAnthropicPayloadPolicy, O as applyAnthropicCacheControlToMessages, S as omitFoundryBearerCredentialHeaders, T as normalizeAnthropicInlineContent, b as resolveAnthropicFallbackServingModelCost, c as normalizeAnthropicToolChoice, d as resolveOriginalAnthropicToolName, f as toClaudeCodeToolName, g as ANTHROPIC_SERVER_SIDE_FALLBACK_BETA, h as ANTHROPIC_SERVER_SIDE_FALLBACKS, j as resolveAnthropicEphemeralCacheControl, k as applyAnthropicEphemeralCacheControlMarkers, l as projectAnthropicTools, m as findActiveAnthropicToolTurnAssistantIndex, n as applyAnthropicMessageStartUsage, p as ANTHROPIC_OMITTED_REASONING_TEXT, s as normalizeAnthropicToolCallId, t as applyAnthropicMessageDeltaUsage, u as reconcileAnthropicToolChoice, v as applyAnthropicFallbackBoundary, w as createAnthropicInlineImageBudget, x as applyAnthropicRefusal, y as readAnthropicFallbackBoundary } from "./anthropic-usage-Ma4iX6uG.mjs";
11
+ import { n as toErrorObject, t as createResponsesPromptEgressObserver } from "./openai-responses-prompt-observer-internal-DDZPxRfr.mjs";
12
+ import { a as convertMessages, c as resolveOpenAICompletionsResponseFormat, d as rememberPendingCommentaryTags, f as tagPendingCommentaryText, i as finalizeOpenAICompletionsToolCalls, l as shouldOmitOllamaCompatResponseFormat, n as mapOpenAIStopReason, o as detectOpenAICompletionsCompat, r as createOpenAICompletionsToolCallDeltaNormalizer, s as resolveOpenAICompletionsCompat, t as resolveOpenAIReasoningEffortMap, u as clearPendingCommentaryText } from "./openai-reasoning-compat-DKebnIBL.mjs";
13
13
  import { t as createDeferredEventBuffer } from "./deferred-event-buffer-DAvyP7qA.mjs";
14
14
  import { n as parseStreamingJson } from "./json-parse-BvXNt1-7.mjs";
15
15
  import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
16
- import { C as resolveSecretSentinel, S as resolveModelHeaderSentinels$1, T as supportsModelTools, _ as isGoogleGemini3ProModel, a as failTransportStream, c as mergeTransportMetadata, d as transportAbortError, f as MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, g as isGoogleGemini3FlashModel, h as isCodeModeModelVisibleToolName, i as createWritableTransportEventStream, l as sanitizeNonEmptyTransportPayloadText, m as estimateStringChars, n as coerceTransportToolCallArguments, o as finalizeTransportStream, p as createAbortError$1, r as createEmptyTransportUsage, s as mergeTransportHeaders, t as assignTransportErrorDetails, u as sanitizeTransportPayloadText, v as parseRetryAfterSeconds, w as sha256Hex, y as readResponseTextSnippet } from "./transport-stream-shared-D81p90xq.mjs";
17
- import { A as normalizeResponsesFailedEvent, B as resolveReplayableResponsesMessageId, C as prepareOpenAIResponsesReasoningItemForReplay, D as applyServiceTierPricing, E as tagOpenAIResponsesReasoningReplayItem, F as summarizeResponsesFailedNoDetailsObservation, G as throwIfModelStreamAborted, H as createModelStreamCooperativeScheduler, I as summarizeResponsesPayload, L as summarizeResponsesTools, M as stringifyRedactedEvent, N as stringifyRedactedPayload, O as buildResponsesFailedNoDetailsObservation, P as summarizeOpenAITransportError, R as AZURE_RESPONSES_FIRST_EVENT_TIMEOUT_MS, S as isInvalidEncryptedContentError, T as stripResponsesRequestEncryptedContent, U as log, V as GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, W as resolvePromptCacheKey, Y as normalizeOpenAIStrictToolParameters, Z as resolveOpenAIProjectedToolsStrictToolFlag, b as convertResponsesMessages, bt as resolveModelPayloadDebugMode, dt as isOpenAIGpt55Model, ft as isOpenAIGpt56Model, gt as supportsOpenAIReasoningEffort, j as safeDebugValue, k as logResponsesFailedNoDetails, mt as resolveOpenAIReasoningEffortForModel, n as processResponsesStream, o as observeResponsesStream, pt as normalizeOpenAIReasoningEffort, q as findOpenAIStrictToolProjectionDiagnostics, t as ResponsesStreamFailure, ut as isOpenAIGpt54MiniModel, v as buildOpenAIResponsesReasoningReplayMetadata, vt as uniqueStrings, w as resolveAzureOpenAIApiVersion, x as createResponsesStreamWithEncryptedContentRetry, xt as resolveModelSseDebugMode, y as buildResponsesInputMessage, yt as emitModelTransportDebug, z as OPENAI_CODEX_RESPONSES_DEFAULT_INSTRUCTIONS } from "./openai-responses-stream-internal-Cw5txaGW.mjs";
16
+ import { A as normalizeResponsesFailedEvent, C as prepareOpenAIResponsesReasoningItemForReplay, D as applyServiceTierPricing, E as tagOpenAIResponsesReasoningReplayItem, F as summarizeResponsesFailedNoDetailsObservation, G as normalizeOpenAIStrictToolParameters, I as summarizeResponsesPayload, L as summarizeResponsesTools, M as stringifyRedactedEvent, N as stringifyRedactedPayload, O as buildResponsesFailedNoDetailsObservation, P as summarizeOpenAITransportError, R as AZURE_RESPONSES_FIRST_EVENT_TIMEOUT_MS, S as isInvalidEncryptedContentError, T as stripResponsesRequestEncryptedContent, U as findOpenAIStrictToolProjectionDiagnostics, V as resolveReplayableResponsesMessageId, _t as resolveModelSseDebugMode, b as convertResponsesMessages, bt as quoteUnsafeIntegerLiterals, ct as isOpenAIGpt56Model, ft as supportsOpenAIReasoningEffort, gt as resolveModelPayloadDebugMode, ht as emitModelTransportDebug, j as safeDebugValue, k as logResponsesFailedNoDetails, lt as normalizeOpenAIReasoningEffort, mt as uniqueStrings, n as processResponsesStream, o as observeResponsesStream, ot as isOpenAIGpt54MiniModel, q as resolveOpenAIProjectedToolsStrictToolFlag, st as isOpenAIGpt55Model, t as ResponsesStreamFailure, ut as resolveOpenAIReasoningEffortForModel, v as buildOpenAIResponsesReasoningReplayMetadata, vt as parseJsonObjectPreservingUnsafeIntegers, w as resolveAzureOpenAIApiVersion, x as createResponsesStreamWithEncryptedContentRetry, y as buildResponsesInputMessage, yt as parseJsonPreservingUnsafeIntegers, z as OPENAI_CODEX_RESPONSES_DEFAULT_INSTRUCTIONS } from "./openai-responses-stream-internal-Bl8YyVtF.mjs";
17
+ import { a as parseStrictPositiveInteger } from "./number-coercion-1Miyb5MO.mjs";
18
+ import { C as resolveSecretSentinel, S as resolveModelHeaderSentinels$1, T as supportsModelTools, _ as isGoogleGemini3ProModel, a as failTransportStream, c as mergeTransportMetadata, d as transportAbortError, f as MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE, g as isGoogleGemini3FlashModel, h as isCodeModeModelVisibleToolName, i as createWritableTransportEventStream, l as sanitizeNonEmptyTransportPayloadText, m as estimateStringChars, n as coerceTransportToolCallArguments, o as finalizeTransportStream, p as createAbortError$1, r as createEmptyTransportUsage, s as mergeTransportHeaders, t as assignTransportErrorDetails, u as sanitizeTransportPayloadText, v as parseRetryAfterSeconds, w as sha256Hex, y as readResponseTextSnippet } from "./transport-stream-shared-CPNv7A3r.mjs";
19
+ import { a as parseOpenAICompletionsUsage, c as throwIfModelStreamAborted, d as reconcileOpenAIResponsesToolChoice, i as log, l as projectOpenAITools, n as createModelStreamCooperativeScheduler, o as readOpenAICompletionsContentDeltas, r as isOpenAICompletionsThinkingEnabled, s as resolvePromptCacheKey, t as GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, u as reconcileOpenAICompletionsToolChoice } from "./openai-transport-shared-Cipt7egQ.mjs";
18
20
  import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-CGDyLWUR.mjs";
19
- import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-BBys9hSb.mjs";
21
+ import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-BIBomOGq.mjs";
20
22
  import { i as resolveAzureDeploymentNameFromMap, t as isOpenAICompatibleAzureResponsesBaseUrl } from "./azure-openai-responses-client-compat-C7K7QfUE.mjs";
23
+ import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
21
24
  import { randomUUID } from "node:crypto";
22
25
  import OpenAI, { AzureOpenAI } from "openai";
23
- //#region packages/ai/src/transports/anthropic-payload-policy.ts
24
- /**
25
- * Anthropic-family request payload policy helpers.
26
- * Applies service-tier and cache-control markers only when provider endpoint
27
- * capabilities allow them.
28
- */
29
- const ANTHROPIC_CACHE_CONTROL_LIMIT = 4;
30
- function resolveBaseUrlHostname(baseUrl) {
31
- try {
32
- return new URL(baseUrl).hostname;
33
- } catch {
34
- return;
35
- }
36
- }
37
- function isLongTtlEligibleEndpoint(baseUrl) {
38
- if (typeof baseUrl !== "string") return false;
39
- const hostname = resolveBaseUrlHostname(baseUrl);
40
- if (!hostname) return false;
41
- return hostname === "api.anthropic.com" || hostname === "aiplatform.googleapis.com" || hostname.endsWith("-aiplatform.googleapis.com");
42
- }
43
- /** Resolve Anthropic cache-control marker retention for a request endpoint. */
44
- function resolveAnthropicEphemeralCacheControl(baseUrl, cacheRetention) {
45
- const retention = resolveCacheRetention(cacheRetention);
46
- if (retention === "none") return;
47
- const ttl = retention === "long" && (cacheRetention === "long" || isLongTtlEligibleEndpoint(baseUrl)) ? "1h" : void 0;
48
- return {
49
- type: "ephemeral",
50
- ...ttl ? { ttl } : {}
51
- };
52
- }
53
- function applyAnthropicCacheControlToSystem(system, cacheControl) {
54
- if (!Array.isArray(system)) return;
55
- const normalizedBlocks = [];
56
- for (const block of system) {
57
- if (!block || typeof block !== "object") {
58
- normalizedBlocks.push(block);
59
- continue;
60
- }
61
- const record = block;
62
- if (record.type !== "text" || typeof record.text !== "string") {
63
- normalizedBlocks.push(block);
64
- continue;
65
- }
66
- const split = splitSystemPromptCacheBoundary(record.text);
67
- if (!split) {
68
- if (record.cache_control === void 0) record.cache_control = cacheControl;
69
- normalizedBlocks.push(record);
70
- continue;
71
- }
72
- const { cache_control: existingCacheControl, ...rest } = record;
73
- if (split.stablePrefix) normalizedBlocks.push({
74
- ...rest,
75
- text: split.stablePrefix,
76
- cache_control: existingCacheControl ?? cacheControl
77
- });
78
- if (split.dynamicSuffix) normalizedBlocks.push({
79
- ...rest,
80
- text: split.dynamicSuffix
81
- });
82
- }
83
- system.splice(0, system.length, ...normalizedBlocks);
84
- }
85
- function stripAnthropicSystemPromptBoundary(system) {
86
- if (!Array.isArray(system)) return;
87
- for (const block of system) {
88
- if (!block || typeof block !== "object") continue;
89
- const record = block;
90
- if (record.type === "text" && typeof record.text === "string") record.text = stripSystemPromptCacheBoundary(record.text);
91
- }
92
- }
93
- function applyAnthropicCacheControlToMessages(messages, cacheControl, markerLimit, cacheBreakpointOptOutMessageIndexes) {
94
- if (!Array.isArray(messages) || messages.length === 0 || markerLimit <= 0) return;
95
- let fallbackToolResult;
96
- for (let i = messages.length - 1; i >= 0; i--) {
97
- const message = messages[i];
98
- if (!message || typeof message !== "object") continue;
99
- const record = message;
100
- if (record.role !== "user" || cacheBreakpointOptOutMessageIndexes.has(i)) continue;
101
- const content = record.content;
102
- if (typeof content === "string") {
103
- if (fallbackToolResult && markerLimit === 1) {
104
- fallbackToolResult.cache_control = cacheControl;
105
- return;
106
- }
107
- record.content = [{
108
- type: "text",
109
- text: content,
110
- cache_control: cacheControl
111
- }];
112
- if (fallbackToolResult && markerLimit > 1) fallbackToolResult.cache_control = cacheControl;
113
- return;
114
- }
115
- if (!Array.isArray(content)) continue;
116
- for (let j = content.length - 1; j >= 0; j--) {
117
- const block = content[j];
118
- if (!block || typeof block !== "object") continue;
119
- const blockRecord = block;
120
- if (blockRecord.type === "text" || blockRecord.type === "image") {
121
- if (fallbackToolResult && markerLimit === 1) {
122
- fallbackToolResult.cache_control = cacheControl;
123
- return;
124
- }
125
- blockRecord.cache_control = cacheControl;
126
- if (fallbackToolResult && markerLimit > 1) fallbackToolResult.cache_control = cacheControl;
127
- return;
128
- }
129
- if (blockRecord.type === "tool_result" && fallbackToolResult === void 0) fallbackToolResult = blockRecord;
130
- }
131
- }
132
- if (fallbackToolResult) fallbackToolResult.cache_control = cacheControl;
133
- }
134
- function countAnthropicCacheControlMarkers(blocks) {
135
- if (!Array.isArray(blocks)) return 0;
136
- let count = 0;
137
- for (const block of blocks) if (block && typeof block === "object" && "cache_control" in block) count += 1;
138
- return count;
139
- }
140
- /** @deprecated Anthropic-family provider payload helper; do not use from third-party plugins. */
141
- function resolveAnthropicPayloadPolicy(input) {
142
- return {
143
- allowsServiceTier: resolveProviderRequestCapabilities({
144
- provider: input.provider,
145
- api: input.api,
146
- baseUrl: input.baseUrl,
147
- capability: "llm",
148
- transport: "stream"
149
- }).allowsAnthropicServiceTier,
150
- cacheControl: input.enableCacheControl === true ? resolveAnthropicEphemeralCacheControl(input.baseUrl, input.cacheRetention) : void 0,
151
- serviceTier: input.serviceTier
152
- };
153
- }
154
- /** @deprecated Anthropic-family provider payload helper; do not use from third-party plugins. */
155
- function applyAnthropicPayloadPolicyToParams(payloadObj, policy, cacheBreakpointOptOutMessageIndexes) {
156
- if (policy.allowsServiceTier && policy.serviceTier !== void 0 && payloadObj.service_tier === void 0) payloadObj.service_tier = policy.serviceTier;
157
- if (policy.cacheControl) applyAnthropicCacheControlToSystem(payloadObj.system, policy.cacheControl);
158
- else stripAnthropicSystemPromptBoundary(payloadObj.system);
159
- if (!policy.cacheControl) return;
160
- const usedMarkers = countAnthropicCacheControlMarkers(payloadObj.system) + countAnthropicCacheControlMarkers(payloadObj.tools);
161
- applyAnthropicCacheControlToMessages(payloadObj.messages, policy.cacheControl, ANTHROPIC_CACHE_CONTROL_LIMIT - usedMarkers, cacheBreakpointOptOutMessageIndexes);
162
- }
163
- /** @deprecated Anthropic-family provider payload helper; do not use from third-party plugins. */
164
- function applyAnthropicEphemeralCacheControlMarkers(payloadObj, cacheControl = { type: "ephemeral" }) {
165
- const messages = payloadObj.messages;
166
- if (!Array.isArray(messages)) return;
167
- for (const message of messages) {
168
- if (message.role === "system" || message.role === "developer") {
169
- if (!cacheControl) continue;
170
- if (typeof message.content === "string") {
171
- message.content = [{
172
- type: "text",
173
- text: message.content,
174
- cache_control: cacheControl
175
- }];
176
- continue;
177
- }
178
- if (Array.isArray(message.content) && message.content.length > 0) {
179
- const last = message.content[message.content.length - 1];
180
- if (last && typeof last === "object") {
181
- const record = last;
182
- if (record.type !== "thinking" && record.type !== "redacted_thinking") record.cache_control = cacheControl;
183
- }
184
- }
185
- continue;
186
- }
187
- if (message.role === "assistant" && Array.isArray(message.content)) for (const block of message.content) {
188
- if (!block || typeof block !== "object") continue;
189
- const record = block;
190
- if (record.type === "thinking" || record.type === "redacted_thinking") delete record.cache_control;
191
- }
192
- }
193
- }
194
- //#endregion
195
- //#region packages/ai/src/transports/json-unsafe-integers.ts
196
- /**
197
- * JSON parsing helpers that preserve integer literals larger than
198
- * Number.MAX_SAFE_INTEGER as strings before JSON.parse can round them.
199
- */
200
- const MAX_SAFE_INTEGER_ABS_STR = String(Number.MAX_SAFE_INTEGER);
201
- function isAsciiDigit(ch) {
202
- return ch !== void 0 && ch >= "0" && ch <= "9";
203
- }
204
- function parseJsonNumberToken(input, start) {
205
- let idx = start;
206
- if (input[idx] === "-") idx += 1;
207
- if (idx >= input.length) return null;
208
- if (input[idx] === "0") idx += 1;
209
- else if (isAsciiDigit(input[idx]) && input[idx] !== "0") while (isAsciiDigit(input[idx])) idx += 1;
210
- else return null;
211
- let isInteger = true;
212
- if (input[idx] === ".") {
213
- isInteger = false;
214
- idx += 1;
215
- if (!isAsciiDigit(input[idx])) return null;
216
- while (isAsciiDigit(input[idx])) idx += 1;
217
- }
218
- if (input[idx] === "e" || input[idx] === "E") {
219
- isInteger = false;
220
- idx += 1;
221
- if (input[idx] === "+" || input[idx] === "-") idx += 1;
222
- if (!isAsciiDigit(input[idx])) return null;
223
- while (isAsciiDigit(input[idx])) idx += 1;
224
- }
225
- return {
226
- token: input.slice(start, idx),
227
- end: idx,
228
- isInteger
229
- };
230
- }
231
- function isUnsafeIntegerLiteral(token) {
232
- const digits = token[0] === "-" ? token.slice(1) : token;
233
- if (digits.length < MAX_SAFE_INTEGER_ABS_STR.length) return false;
234
- if (digits.length > MAX_SAFE_INTEGER_ABS_STR.length) return true;
235
- return digits > MAX_SAFE_INTEGER_ABS_STR;
236
- }
237
- /** Quotes integer literals above Number.MAX_SAFE_INTEGER before JSON.parse. */
238
- function quoteUnsafeIntegerLiterals(input) {
239
- let out = "";
240
- let inString = false;
241
- let escaped = false;
242
- let idx = 0;
243
- while (idx < input.length) {
244
- const ch = input[idx] ?? "";
245
- if (inString) {
246
- out += ch;
247
- if (escaped) escaped = false;
248
- else if (ch === "\\") escaped = true;
249
- else if (ch === "\"") inString = false;
250
- idx += 1;
251
- continue;
252
- }
253
- if (ch === "\"") {
254
- inString = true;
255
- out += ch;
256
- idx += 1;
257
- continue;
258
- }
259
- if (ch === "-" || isAsciiDigit(ch)) {
260
- const parsed = parseJsonNumberToken(input, idx);
261
- if (parsed) {
262
- if (parsed.isInteger && isUnsafeIntegerLiteral(parsed.token)) out += `"${parsed.token}"`;
263
- else out += parsed.token;
264
- idx = parsed.end;
265
- continue;
266
- }
267
- }
268
- out += ch;
269
- idx += 1;
270
- }
271
- return out;
272
- }
273
- /** Parses JSON while preserving unsafe integer literals as strings. */
274
- function parseJsonPreservingUnsafeIntegers(input) {
275
- return JSON.parse(quoteUnsafeIntegerLiterals(input));
276
- }
277
- /** Parses or accepts an object while preserving unsafe integer literals in string input. */
278
- function parseJsonObjectPreservingUnsafeIntegers(value) {
279
- if (typeof value === "string") {
280
- try {
281
- const parsed = parseJsonPreservingUnsafeIntegers(value);
282
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
283
- } catch {
284
- return null;
285
- }
286
- return null;
287
- }
288
- if (value && typeof value === "object" && !Array.isArray(value)) return value;
289
- return null;
290
- }
291
- //#endregion
292
26
  //#region packages/ai/src/transports/anthropic-transport-stream.ts
293
27
  /**
294
28
  * Native Anthropic Messages streaming transport.
295
29
  * Converts OpenClaw contexts/tools into Anthropic payloads, streams SSE events
296
30
  * back into runtime output blocks, and applies provider request policy.
297
31
  */
298
- const CLAUDE_CODE_VERSION = "2.1.75";
299
- const CLAUDE_CODE_BILLING_SYSTEM_BLOCK = `x-anthropic-billing-header: cc_version=${CLAUDE_CODE_VERSION}; cc_entrypoint=sdk-cli;`;
300
32
  const ANTHROPIC_MESSAGES_ERROR_BODY_MAX_BYTES = 8 * 1024;
301
33
  const ANTHROPIC_MESSAGES_ERROR_BODY_MAX_CHARS = 400;
302
34
  const ANTHROPIC_MESSAGES_ERROR_BODY_READ_IDLE_TIMEOUT_MS = 1e4;
303
35
  const ANTHROPIC_MESSAGES_DEFAULT_MAX_TOKENS = 4096;
304
36
  const ANTHROPIC_MESSAGES_FALLBACK_CONTEXT_DIVISOR = 4;
305
37
  const ANTHROPIC_MESSAGES_SSE_PENDING_BUFFER_MAX_CHARS = 16 * 1024 * 1024;
306
- const CLAUDE_CODE_TOOL_LOOKUP = new Map([
307
- "Read",
308
- "Write",
309
- "Edit",
310
- "Bash",
311
- "Grep",
312
- "Glob",
313
- "AskUserQuestion",
314
- "EnterPlanMode",
315
- "ExitPlanMode",
316
- "KillShell",
317
- "NotebookEdit",
318
- "Skill",
319
- "Task",
320
- "TaskOutput",
321
- "TodoWrite",
322
- "WebFetch",
323
- "WebSearch"
324
- ].map((tool) => [normalizeLowercaseStringOrEmpty(tool), tool]));
325
38
  function resolveAnthropicRequestModelId(model) {
326
39
  if (isDirectAnthropicModel(model) && /^anthropic\//i.test(model.id)) return model.id.replace(/^anthropic\//i, "");
327
40
  return model.id;
328
41
  }
329
42
  const EMPTY_ANTHROPIC_MESSAGES_FALLBACK_TEXT = ".";
330
- function normalizeAnthropicToolChoice(thinkingEnabled, toolChoice) {
331
- if (thinkingEnabled && (toolChoice === "any" || typeof toolChoice === "object" && toolChoice.type === "tool")) return { type: "auto" };
332
- return typeof toolChoice === "string" ? { type: toolChoice } : toolChoice;
333
- }
334
- function supportsNativeXhighEffort(model) {
335
- return supportsClaudeNativeXhighEffort(model);
336
- }
337
- function supportsAdaptiveThinking(model) {
338
- return supportsClaudeAdaptiveThinking(model);
339
- }
340
- function mapThinkingLevelToEffort(level, model) {
341
- const thinkingLevelMap = resolveClaudeNativeThinkingLevelMap(model);
342
- const resolvedLevel = clampThinkingLevel({
343
- ...model,
344
- ...typeof model.params?.canonicalModelId === "string" ? { reasoning: true } : {},
345
- ...thinkingLevelMap ? { thinkingLevelMap } : {}
346
- }, level);
347
- const mapped = thinkingLevelMap?.[resolvedLevel];
348
- if (typeof mapped === "string") return mapped;
349
- switch (resolvedLevel) {
350
- case "off":
351
- case "minimal":
352
- case "low": return "low";
353
- case "medium": return "medium";
354
- case "xhigh": return supportsNativeXhighEffort(model) ? "xhigh" : "high";
355
- case "max": return supportsClaudeNativeMaxEffort(model) ? "max" : "high";
356
- default: return "high";
357
- }
358
- }
359
- function clampReasoningLevel(level) {
360
- return level === "xhigh" || level === "max" ? "high" : level;
361
- }
362
43
  function resolvePositiveAnthropicTokenLimit(value) {
363
44
  if (typeof value !== "number" || !Number.isFinite(value)) return;
364
45
  const floored = Math.floor(value);
@@ -373,23 +54,6 @@ function resolveAnthropicMessagesMaxTokens(params) {
373
54
  const contextWindow = resolvePositiveAnthropicTokenLimit(params.modelContextWindow);
374
55
  return contextWindow === void 0 ? ANTHROPIC_MESSAGES_DEFAULT_MAX_TOKENS : Math.max(1, Math.min(ANTHROPIC_MESSAGES_DEFAULT_MAX_TOKENS, Math.floor(contextWindow / ANTHROPIC_MESSAGES_FALLBACK_CONTEXT_DIVISOR)));
375
56
  }
376
- function adjustMaxTokensForThinking(params) {
377
- const budgets = {
378
- minimal: 1024,
379
- low: 2048,
380
- medium: 8192,
381
- high: 16384,
382
- ...params.customBudgets
383
- };
384
- const minOutputTokens = 1024;
385
- let thinkingBudget = budgets[clampReasoningLevel(params.reasoningLevel)];
386
- const maxTokens = Math.min(params.baseMaxTokens + thinkingBudget, params.modelMaxTokens);
387
- if (maxTokens <= thinkingBudget) thinkingBudget = Math.max(0, maxTokens - minOutputTokens);
388
- return {
389
- maxTokens,
390
- thinkingBudget
391
- };
392
- }
393
57
  function isAnthropicOAuthToken(apiKey) {
394
58
  return (resolveSecretSentinel(apiKey) ?? apiKey).includes("sk-ant-oat");
395
59
  }
@@ -416,9 +80,6 @@ function buildAnthropicBetaHeader(model, betaFeatures, params) {
416
80
  if (!isDirectAnthropicModel(model)) return;
417
81
  return params.oauth ? `claude-code-20250219,oauth-2025-04-20,${betaFeatures.join(",")}` : betaFeatures.join(",");
418
82
  }
419
- function toClaudeCodeName(name) {
420
- return CLAUDE_CODE_TOOL_LOOKUP.get(normalizeLowercaseStringOrEmpty(name)) ?? name;
421
- }
422
83
  const NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
423
84
  async function convertContentBlocks(content, model, imageBudget) {
424
85
  const text = extractToolResultText(content);
@@ -459,15 +120,12 @@ async function convertContentBlocks(content, model, imageBudget) {
459
120
  });
460
121
  return blocks;
461
122
  }
462
- function normalizeToolCallId(id) {
463
- return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
464
- }
465
123
  async function convertAnthropicMessages(messages, model, isOAuthToken, options) {
466
124
  const params = [];
467
125
  const imageBudget = createAnthropicInlineImageBudget();
468
126
  const allowReasoningContentReplay = options.allowReasoningContentReplay === true;
469
127
  const replayThinkingEnabled = options.replayThinkingEnabled !== false;
470
- const transformedMessages = transformTransportMessages(messages, model, normalizeToolCallId);
128
+ const transformedMessages = transformTransportMessages(messages, model, normalizeAnthropicToolCallId);
471
129
  const activeToolTurnAssistantIndex = replayThinkingEnabled ? -1 : findActiveAnthropicToolTurnAssistantIndex(transformedMessages);
472
130
  for (let i = 0; i < transformedMessages.length; i += 1) {
473
131
  const msg = transformedMessages[i];
@@ -566,7 +224,7 @@ async function convertAnthropicMessages(messages, model, isOAuthToken, options)
566
224
  if (block.type === "toolCall") blocks.push({
567
225
  type: "tool_use",
568
226
  id: block.id,
569
- name: isOAuthToken ? toClaudeCodeName(block.name) : block.name,
227
+ name: isOAuthToken ? toClaudeCodeToolName(block.name) : block.name,
570
228
  input: coerceTransportToolCallArguments(block.arguments)
571
229
  });
572
230
  }
@@ -625,7 +283,7 @@ function ensureNonEmptyAnthropicMessages(messages) {
625
283
  }];
626
284
  }
627
285
  function convertAnthropicTools(tools, isOAuthToken) {
628
- const projection = projectAnthropicTools(tools ?? [], (name) => isOAuthToken ? toClaudeCodeName(name) : name);
286
+ const projection = projectAnthropicTools(tools ?? [], (name) => isOAuthToken ? toClaudeCodeToolName(name) : name);
629
287
  const converted = [];
630
288
  for (const tool of projection.tools) converted.push({
631
289
  name: tool.wireName,
@@ -640,18 +298,6 @@ function convertAnthropicTools(tools, isOAuthToken) {
640
298
  function parseAnthropicToolCallArguments(inputJson) {
641
299
  return parseJsonObjectPreservingUnsafeIntegers(inputJson) ?? parseStreamingJson(inputJson);
642
300
  }
643
- function mapStopReason(reason) {
644
- switch (reason) {
645
- case "end_turn": return "stop";
646
- case "max_tokens": return "length";
647
- case "tool_use": return "toolUse";
648
- case "pause_turn": return "stop";
649
- case "refusal":
650
- case "sensitive": return "error";
651
- case "stop_sequence": return "stop";
652
- default: throw new Error(`Unhandled stop reason: ${String(reason)}`);
653
- }
654
- }
655
301
  const DEFAULT_ANTHROPIC_BASE_URL = "https://api.anthropic.com";
656
302
  /** Resolve the effective Anthropic API base URL from model or environment. */
657
303
  function resolveAnthropicBaseUrl(baseUrl) {
@@ -794,7 +440,7 @@ async function readAnthropicMessagesErrorBodySnippet(response) {
794
440
  }
795
441
  function createAnthropicTransportClient(params) {
796
442
  const { model, context, apiKey, options } = params;
797
- const needsInterleavedBeta = (options?.interleavedThinking ?? true) && !supportsAdaptiveThinking(model);
443
+ const needsInterleavedBeta = (options?.interleavedThinking ?? true) && !supportsClaudeAdaptiveThinking(model);
798
444
  const fetch = isKimiAnthropicProvider(model.provider) && options?.thinkingEnabled === true ? buildGuardedModelFetch(model, void 0, { sanitizeSse: false }) : buildGuardedModelFetch(model);
799
445
  if (model.provider === "github-copilot") {
800
446
  const betaFeatures = needsInterleavedBeta ? ["interleaved-thinking-2025-05-14"] : [];
@@ -843,7 +489,7 @@ function createAnthropicTransportClient(params) {
843
489
  accept: "application/json",
844
490
  "anthropic-dangerous-direct-browser-access": "true",
845
491
  ...betaHeader ? { "anthropic-beta": betaHeader } : {},
846
- "user-agent": `claude-cli/${CLAUDE_CODE_VERSION}`,
492
+ "user-agent": `claude-cli/${ANTHROPIC_CLAUDE_CODE_VERSION}`,
847
493
  "x-app": "cli"
848
494
  }, model.headers, options?.headers),
849
495
  fetch
@@ -899,7 +545,7 @@ async function buildAnthropicParams(model, context, isOAuthToken, options) {
899
545
  if (isOAuthToken) params.system = [
900
546
  {
901
547
  type: "text",
902
- text: CLAUDE_CODE_BILLING_SYSTEM_BLOCK
548
+ text: ANTHROPIC_CLAUDE_CODE_BILLING_SYSTEM_BLOCK
903
549
  },
904
550
  {
905
551
  type: "text",
@@ -914,7 +560,7 @@ async function buildAnthropicParams(model, context, isOAuthToken, options) {
914
560
  type: "text",
915
561
  text: sanitizeTransportPayloadText(context.systemPrompt)
916
562
  }];
917
- if (options?.temperature !== void 0 && !options.thinkingEnabled && !supportsNativeXhighEffort(model)) params.temperature = options.temperature;
563
+ if (options?.temperature !== void 0 && !options.thinkingEnabled && !supportsClaudeNativeXhighEffort(model)) params.temperature = options.temperature;
918
564
  if (options?.stop !== void 0 && options.stop.length > 0) params.stop_sequences = options.stop;
919
565
  let toolProjection;
920
566
  if (context.tools) {
@@ -922,8 +568,8 @@ async function buildAnthropicParams(model, context, isOAuthToken, options) {
922
568
  toolProjection = convertedTools.projection;
923
569
  if (convertedTools.tools.length > 0) params.tools = convertedTools.tools;
924
570
  }
925
- if (mandatoryAdaptiveThinking || model.reasoning || supportsAdaptiveThinking(model)) {
926
- if (mandatoryAdaptiveThinking || options?.thinkingEnabled) if (supportsAdaptiveThinking(model)) {
571
+ if (mandatoryAdaptiveThinking || model.reasoning || supportsClaudeAdaptiveThinking(model)) {
572
+ if (mandatoryAdaptiveThinking || options?.thinkingEnabled) if (supportsClaudeAdaptiveThinking(model)) {
927
573
  params.thinking = {
928
574
  type: "adaptive",
929
575
  display: options?.thinkingDisplay ?? "summarized"
@@ -985,17 +631,12 @@ function resolveAnthropicTransportOptions(model, options, apiKey) {
985
631
  if (resolved.thinkingEnabled) resolved.effort = "high";
986
632
  return resolved;
987
633
  }
988
- if (supportsAdaptiveThinking(model)) {
634
+ if (supportsClaudeAdaptiveThinking(model)) {
989
635
  resolved.thinkingEnabled = true;
990
- resolved.effort = mapThinkingLevelToEffort(reasoning, model);
636
+ resolved.effort = resolveAnthropicThinkingEffort(model, reasoning);
991
637
  return resolved;
992
638
  }
993
- const adjusted = adjustMaxTokensForThinking({
994
- baseMaxTokens,
995
- modelMaxTokens: reasoningModelMaxTokens,
996
- reasoningLevel: reasoning,
997
- customBudgets: options?.thinkingBudgets
998
- });
639
+ const adjusted = adjustMaxTokensForThinking(baseMaxTokens, reasoningModelMaxTokens, reasoning === "max" ? "high" : reasoning, options?.thinkingBudgets);
999
640
  const thinkingEnabled = adjusted.thinkingBudget >= 1024;
1000
641
  resolved.maxTokens = adjusted.maxTokens;
1001
642
  resolved.thinkingEnabled = thinkingEnabled;
@@ -1153,23 +794,7 @@ function createAnthropicMessagesTransportStreamFn() {
1153
794
  const usage = message?.usage ?? {};
1154
795
  output.responseId = typeof message?.id === "string" ? message.id : void 0;
1155
796
  output.responseModel = typeof message?.model === "string" ? message.model : void 0;
1156
- const promptUsage = readAnthropicPromptUsageSnapshot(usage);
1157
- const messageStartPromptTokens = promptUsage ? promptUsage.input + promptUsage.cacheRead + promptUsage.cacheWrite : 0;
1158
- messageStartPromptUsage = messageStartPromptTokens > 0 ? promptUsage : void 0;
1159
- const inputTokens = readAnthropicUsageTokenCount(usage.input_tokens);
1160
- if (inputTokens !== void 0) output.usage.input = inputTokens;
1161
- const outputTokens = readAnthropicUsageTokenCount(usage.output_tokens);
1162
- if (outputTokens !== void 0) output.usage.output = outputTokens;
1163
- const cacheReadTokens = usage.cache_read_input_tokens == null ? 0 : readAnthropicUsageTokenCount(usage.cache_read_input_tokens);
1164
- if (cacheReadTokens !== void 0) output.usage.cacheRead = cacheReadTokens;
1165
- const cacheWriteTokens = usage.cache_creation_input_tokens == null ? 0 : readAnthropicUsageTokenCount(usage.cache_creation_input_tokens);
1166
- if (cacheWriteTokens !== void 0) output.usage.cacheWrite = cacheWriteTokens;
1167
- output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
1168
- if (messageStartPromptUsage && outputTokens !== void 0) output.usage.contextUsage = {
1169
- state: "available",
1170
- promptTokens: messageStartPromptTokens,
1171
- totalTokens: messageStartPromptTokens + output.usage.output
1172
- };
797
+ messageStartPromptUsage = applyAnthropicMessageStartUsage(output.usage, usage);
1173
798
  calculateCost(costModel, output.usage);
1174
799
  eventSink.push({
1175
800
  type: "start",
@@ -1447,31 +1072,8 @@ function createAnthropicMessagesTransportStreamFn() {
1447
1072
  const delta = event.delta;
1448
1073
  const usage = event.usage;
1449
1074
  if (delta?.stop_reason) if (delta.stop_reason === "refusal") applyAnthropicRefusal(output, delta.stop_details, model.provider);
1450
- else output.stopReason = mapStopReason(delta.stop_reason);
1451
- const inputTokens = readAnthropicUsageTokenCount(usage?.input_tokens);
1452
- if (inputTokens !== void 0) output.usage.input = inputTokens;
1453
- const outputTokens = readAnthropicUsageTokenCount(usage?.output_tokens);
1454
- if (outputTokens !== void 0) output.usage.output = outputTokens;
1455
- const cacheReadTokens = readAnthropicUsageTokenCount(usage?.cache_read_input_tokens);
1456
- if (cacheReadTokens !== void 0) output.usage.cacheRead = cacheReadTokens;
1457
- const cacheWriteTokens = readAnthropicUsageTokenCount(usage?.cache_creation_input_tokens);
1458
- if (cacheWriteTokens !== void 0) output.usage.cacheWrite = cacheWriteTokens;
1459
- output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
1460
- const iterationUsage = readLastAnthropicIterationUsage(usage ?? {});
1461
- if (iterationUsage.state === "valid") output.usage.contextUsage = {
1462
- state: "available",
1463
- promptTokens: iterationUsage.usage.contextPromptTokens,
1464
- totalTokens: iterationUsage.usage.totalTokens
1465
- };
1466
- else if (iterationUsage.state === "invalid") output.usage.contextUsage = { state: "unavailable" };
1467
- else if (outputTokens !== void 0 && (messageStartPromptUsage !== void 0 || inputTokens !== void 0 && cacheReadTokens !== void 0 && cacheWriteTokens !== void 0)) {
1468
- const promptTokens = output.usage.input + output.usage.cacheRead + output.usage.cacheWrite;
1469
- output.usage.contextUsage = {
1470
- state: "available",
1471
- promptTokens,
1472
- totalTokens: promptTokens + output.usage.output
1473
- };
1474
- } else output.usage.contextUsage = { state: "unavailable" };
1075
+ else output.stopReason = mapAnthropicStopReason(delta.stop_reason);
1076
+ applyAnthropicMessageDeltaUsage(output.usage, usage, messageStartPromptUsage);
1475
1077
  calculateCost(costModel, output.usage);
1476
1078
  if (output.stopReason === "toolUse" || output.content.some((block) => block.type === "toolCall")) tagPendingCommentaryText(output.content);
1477
1079
  flushPendingTextEnds();
@@ -2098,7 +1700,11 @@ function createOpenAICompletionsTransportStreamFn() {
2098
1700
  stream,
2099
1701
  output,
2100
1702
  signal: options?.signal,
2101
- error
1703
+ error,
1704
+ cleanup: () => {
1705
+ output.stopReason = options?.signal?.aborted ? "aborted" : "error";
1706
+ finalizeOpenAICompletionsToolCalls(output, { allowSilentToolCallPromotion: false });
1707
+ }
2102
1708
  });
2103
1709
  } finally {
2104
1710
  firstEventAbort?.dispose();
@@ -2124,6 +1730,7 @@ async function processOpenAICompletionsStream(responseStream, output, model, str
2124
1730
  const provisionalCommentaryTags = /* @__PURE__ */ new Map();
2125
1731
  const toolCallBlockBytes = /* @__PURE__ */ new WeakMap();
2126
1732
  const toolCallBlockIndices = /* @__PURE__ */ new WeakMap();
1733
+ const normalizeToolCallDeltas = createOpenAICompletionsToolCallDeltaNormalizer();
2127
1734
  let sawStopFinishReason = false;
2128
1735
  let sawNativeToolCallDelta = false;
2129
1736
  const blockIndex = () => output.content.length - 1;
@@ -2296,10 +1903,7 @@ async function processOpenAICompletionsStream(responseStream, output, model, str
2296
1903
  const latestBlock = output.content[output.content.length - 1];
2297
1904
  if (currentBlock?.type === "text" || currentBlock?.type === "toolCall") return;
2298
1905
  if (latestBlock?.type === "text" || latestBlock?.type === "toolCall") return;
2299
- appendThinkingDelta({
2300
- signature: "",
2301
- text: ""
2302
- });
1906
+ appendThinkingDelta({ text: "" });
2303
1907
  };
2304
1908
  const flushReasoningTagTextPartitionerAtEnd = () => {
2305
1909
  for (const delta of reasoningTagTextPartitioner.flush()) appendPartitionedVisibleDelta(delta);
@@ -2327,7 +1931,7 @@ async function processOpenAICompletionsStream(responseStream, output, model, str
2327
1931
  output.responseId ||= chunk.id;
2328
1932
  let hasReasoningUsageActivity = false;
2329
1933
  if (chunk.usage) {
2330
- output.usage = parseTransportChunkUsage(chunk.usage, model);
1934
+ output.usage = parseOpenAICompletionsUsage(chunk.usage, model);
2331
1935
  hasReasoningUsageActivity = hasOpenAICompletionsReasoningUsageActivity(chunk.usage);
2332
1936
  }
2333
1937
  const choice = Array.isArray(chunk.choices) ? chunk.choices[0] : void 0;
@@ -2338,7 +1942,7 @@ async function processOpenAICompletionsStream(responseStream, output, model, str
2338
1942
  }
2339
1943
  const choiceUsage = choice.usage;
2340
1944
  if (!chunk.usage && choiceUsage) {
2341
- output.usage = parseTransportChunkUsage(choiceUsage, model);
1945
+ output.usage = parseOpenAICompletionsUsage(choiceUsage, model);
2342
1946
  hasReasoningUsageActivity = hasOpenAICompletionsReasoningUsageActivity(choiceUsage);
2343
1947
  }
2344
1948
  if (choice.finish_reason) {
@@ -2347,91 +1951,92 @@ async function processOpenAICompletionsStream(responseStream, output, model, str
2347
1951
  if (finishReasonResult.stopReason === "stop") sawStopFinishReason = true;
2348
1952
  if (finishReasonResult.errorMessage) output.errorMessage = finishReasonResult.errorMessage;
2349
1953
  }
2350
- const choiceDelta = choice.delta ?? choice.message;
2351
- if (!choiceDelta) {
1954
+ const rawChoiceDelta = choice.delta ?? choice.message;
1955
+ if (!rawChoiceDelta) {
2352
1956
  emitReasoningUsageActivity(hasReasoningUsageActivity);
2353
1957
  await cooperativeScheduler.afterEvent();
2354
1958
  continue;
2355
1959
  }
2356
- const reasoningDeltas = getCompletionsReasoningDeltas(choiceDelta, compat.visibleReasoningDetailTypes);
2357
- const hasMirroredReasoning = reasoningDeltas.some((delta) => delta.kind === "thinking");
2358
- if (hasMirroredReasoning) reasoningTagTextPartitioner.markStrict();
2359
- if (choiceDelta.content) {
2360
- const contentDeltas = getCompletionsContentDeltas(choiceDelta.content);
1960
+ for (const normalizedDelta of normalizeToolCallDeltas(rawChoiceDelta, choice.finish_reason)) {
1961
+ const choiceDelta = normalizedDelta.delta;
1962
+ const reasoningDeltas = getCompletionsReasoningDeltas(choiceDelta, compat.visibleReasoningDetailTypes);
1963
+ const hasMirroredReasoning = reasoningDeltas.some((delta) => delta.kind === "thinking");
1964
+ if (hasMirroredReasoning) reasoningTagTextPartitioner.markStrict();
1965
+ const contentDeltas = readOpenAICompletionsContentDeltas(choiceDelta.content, choiceDelta.refusal, reasoningDeltas.filter((reasoningDelta) => reasoningDelta.kind === "thinking").map((reasoningDelta) => reasoningDelta.text));
1966
+ const appendReasoningDeltas = () => {
1967
+ for (const reasoningDelta of reasoningDeltas) {
1968
+ if (reasoningDelta.kind === "thinking" && !emitReasoning) continue;
1969
+ if (currentBlock?.type === "toolCall") {
1970
+ queuePostToolCallDelta({ ...reasoningDelta });
1971
+ continue;
1972
+ }
1973
+ if (reasoningDelta.kind === "text") appendTextDelta(reasoningDelta.text);
1974
+ else if (emitReasoning) appendThinkingDelta(reasoningDelta);
1975
+ }
1976
+ };
1977
+ if (hasMirroredReasoning) appendReasoningDeltas();
2361
1978
  for (const contentDelta of contentDeltas) if (contentDelta.kind === "text") {
2362
1979
  const routedDeltas = hasMirroredReasoning ? reasoningTagTextPartitioner.push(contentDelta.text) : reasoningTagTextPartitioner.pushVisible(contentDelta.text);
2363
1980
  for (const routedDelta of routedDeltas) appendPartitionedVisibleDelta(routedDelta);
2364
1981
  } else {
2365
- reasoningTagTextPartitioner.markStrict();
1982
+ if (reasoningTagTextPartitioner.hasPending()) reasoningTagTextPartitioner.markStrict();
2366
1983
  appendRoutedContentDelta(contentDelta);
2367
1984
  }
2368
- }
2369
- const refusalText = typeof choiceDelta.refusal === "string" ? choiceDelta.refusal : "";
2370
- if (refusalText) {
2371
- const routedDeltas = hasMirroredReasoning ? reasoningTagTextPartitioner.push(refusalText) : reasoningTagTextPartitioner.pushVisible(refusalText);
2372
- for (const routedDelta of routedDeltas) appendPartitionedVisibleDelta(routedDelta);
2373
- }
2374
- for (const reasoningDelta of reasoningDeltas) {
2375
- if (reasoningDelta.kind === "thinking" && !emitReasoning) continue;
2376
- if (currentBlock?.type === "toolCall") {
2377
- queuePostToolCallDelta({ ...reasoningDelta });
2378
- continue;
2379
- }
2380
- if (reasoningDelta.kind === "text") appendTextDelta(reasoningDelta.text);
2381
- else if (emitReasoning) appendThinkingDelta(reasoningDelta);
2382
- }
2383
- if (choiceDelta.tool_calls && choiceDelta.tool_calls.length > 0) {
2384
- sawNativeToolCallDelta = true;
2385
- flushReasoningTagTextPartitionerAtEnd();
2386
- rememberPendingCommentaryTags(provisionalCommentaryTags, tagPendingCommentaryText(output.content));
2387
- for (const toolCall of choiceDelta.tool_calls) {
2388
- const streamIndex = typeof toolCall.index === "number" ? toolCall.index : void 0;
2389
- let block = streamIndex !== void 0 ? toolCallBlocksByIndex.get(streamIndex) : void 0;
2390
- if (!block && toolCall.id) block = toolCallBlocksById.get(toolCall.id);
2391
- if (!block) {
2392
- if (currentBlock?.type === "toolCall") {
2393
- currentBlock = null;
2394
- flushPendingPostToolCallDeltas();
1985
+ if (!hasMirroredReasoning) appendReasoningDeltas();
1986
+ const toolCallDeltas = normalizedDelta.toolCalls;
1987
+ if (toolCallDeltas.length > 0) {
1988
+ sawNativeToolCallDelta = true;
1989
+ flushReasoningTagTextPartitionerAtEnd();
1990
+ rememberPendingCommentaryTags(provisionalCommentaryTags, tagPendingCommentaryText(output.content));
1991
+ for (const toolCall of toolCallDeltas) {
1992
+ const streamIndex = typeof toolCall.index === "number" ? toolCall.index : void 0;
1993
+ let block = streamIndex !== void 0 ? toolCallBlocksByIndex.get(streamIndex) : void 0;
1994
+ if (!block && toolCall.id) block = toolCallBlocksById.get(toolCall.id);
1995
+ if (!block) {
1996
+ if (currentBlock?.type === "toolCall") {
1997
+ currentBlock = null;
1998
+ flushPendingPostToolCallDeltas();
1999
+ }
2000
+ const initialSig = extractGoogleThoughtSignature(toolCall);
2001
+ block = {
2002
+ type: "toolCall",
2003
+ id: toolCall.id || "",
2004
+ name: toolCall.function?.name || "",
2005
+ arguments: {},
2006
+ partialArgs: "",
2007
+ ...initialSig ? { thoughtSignature: initialSig } : {}
2008
+ };
2009
+ output.content.push(block);
2010
+ toolCallBlockIndices.set(block, output.content.length - 1);
2011
+ pushStreamEvent({
2012
+ type: "toolcall_start",
2013
+ contentIndex: toolCallBlockIndices.get(block) ?? -1,
2014
+ partial: output
2015
+ });
2016
+ }
2017
+ if (streamIndex !== void 0 && !toolCallBlocksByIndex.has(streamIndex)) toolCallBlocksByIndex.set(streamIndex, block);
2018
+ if (toolCall.id) {
2019
+ block.id = toolCall.id;
2020
+ toolCallBlocksById.set(toolCall.id, block);
2021
+ }
2022
+ currentBlock = block;
2023
+ if (toolCall.function?.name) block.name = toolCall.function.name;
2024
+ const deltaSig = extractGoogleThoughtSignature(toolCall);
2025
+ if (deltaSig) block.thoughtSignature = deltaSig;
2026
+ if (toolCall.function?.arguments) {
2027
+ const nextArgumentBytes = measureUtf8Bytes(toolCall.function.arguments);
2028
+ const currentBlockArgBytes = toolCallBlockBytes.get(block) ?? 0;
2029
+ if (currentBlockArgBytes + nextArgumentBytes > MAX_TOOL_CALL_ARGUMENT_BUFFER_BYTES) throw new Error("Exceeded tool-call argument buffer limit");
2030
+ toolCallBlockBytes.set(block, currentBlockArgBytes + nextArgumentBytes);
2031
+ block.partialArgs += toolCall.function.arguments;
2032
+ block.arguments = parseStreamingJson(block.partialArgs);
2033
+ pushStreamEvent({
2034
+ type: "toolcall_delta",
2035
+ contentIndex: toolCallBlockIndices.get(block) ?? -1,
2036
+ delta: toolCall.function.arguments,
2037
+ partial: output
2038
+ });
2395
2039
  }
2396
- const initialSig = extractGoogleThoughtSignature(toolCall);
2397
- block = {
2398
- type: "toolCall",
2399
- id: toolCall.id || "",
2400
- name: toolCall.function?.name || "",
2401
- arguments: {},
2402
- partialArgs: "",
2403
- ...initialSig ? { thoughtSignature: initialSig } : {}
2404
- };
2405
- output.content.push(block);
2406
- toolCallBlockIndices.set(block, output.content.length - 1);
2407
- pushStreamEvent({
2408
- type: "toolcall_start",
2409
- contentIndex: toolCallBlockIndices.get(block) ?? -1,
2410
- partial: output
2411
- });
2412
- }
2413
- if (streamIndex !== void 0 && !toolCallBlocksByIndex.has(streamIndex)) toolCallBlocksByIndex.set(streamIndex, block);
2414
- if (toolCall.id) {
2415
- block.id = toolCall.id;
2416
- toolCallBlocksById.set(toolCall.id, block);
2417
- }
2418
- currentBlock = block;
2419
- if (toolCall.function?.name) block.name = toolCall.function.name;
2420
- const deltaSig = extractGoogleThoughtSignature(toolCall);
2421
- if (deltaSig) block.thoughtSignature = deltaSig;
2422
- if (toolCall.function?.arguments) {
2423
- const nextArgumentBytes = measureUtf8Bytes(toolCall.function.arguments);
2424
- const currentBlockArgBytes = toolCallBlockBytes.get(block) ?? 0;
2425
- if (currentBlockArgBytes + nextArgumentBytes > MAX_TOOL_CALL_ARGUMENT_BUFFER_BYTES) throw new Error("Exceeded tool-call argument buffer limit");
2426
- toolCallBlockBytes.set(block, currentBlockArgBytes + nextArgumentBytes);
2427
- block.partialArgs += toolCall.function.arguments;
2428
- block.arguments = parseStreamingJson(block.partialArgs);
2429
- pushStreamEvent({
2430
- type: "toolcall_delta",
2431
- contentIndex: toolCallBlockIndices.get(block) ?? -1,
2432
- delta: toolCall.function.arguments,
2433
- partial: output
2434
- });
2435
2040
  }
2436
2041
  }
2437
2042
  }
@@ -2444,11 +2049,17 @@ async function processOpenAICompletionsStream(responseStream, output, model, str
2444
2049
  flushDeepSeekTextFilterAtEnd();
2445
2050
  currentBlock = null;
2446
2051
  flushPendingPostToolCallDeltas();
2447
- const hasToolCalls = output.content.some((block) => block.type === "toolCall");
2448
- const hasVisibleText = output.content.some((block) => block.type === "text" && typeof block.text === "string" && block.text.trim().length > 0);
2449
- if (output.stopReason === "toolUse" && !hasToolCalls) output.stopReason = "stop";
2450
- if (output.stopReason === "stop" && hasToolCalls && !hasVisibleText && (sawStopFinishReason || sawNativeToolCallDelta && (options?.sawStreamDONE?.() ?? false))) output.stopReason = "toolUse";
2451
- if (hasToolCalls && output.stopReason !== "toolUse") output.content = output.content.filter((block) => block.type !== "toolCall");
2052
+ finalizeOpenAICompletionsToolCalls(output, {
2053
+ allowSilentToolCallPromotion: sawStopFinishReason || sawNativeToolCallDelta && (options?.sawStreamDONE?.() ?? false),
2054
+ onConfirmedToolCall(block, contentIndex) {
2055
+ pushStreamEvent({
2056
+ type: "toolcall_end",
2057
+ contentIndex,
2058
+ toolCall: block,
2059
+ partial: output
2060
+ });
2061
+ }
2062
+ });
2452
2063
  if (output.stopReason !== "toolUse") clearPendingCommentaryText(provisionalCommentaryTags);
2453
2064
  if (output.stopReason === "toolUse") tagPendingCommentaryText(output.content);
2454
2065
  }
@@ -2463,42 +2074,80 @@ const DEEPSEEK_DSML_TOOL_KINDS = [
2463
2074
  ];
2464
2075
  const DEEPSEEK_DSML_TOOL_OPEN_TOKENS = DEEPSEEK_DSML_BARS.flatMap((bar) => DEEPSEEK_DSML_TOOL_KINDS.map((kind) => `<${bar}DSML${bar}${kind}>`));
2465
2076
  const DEEPSEEK_DSML_TOOL_CLOSE_TOKENS = DEEPSEEK_DSML_BARS.flatMap((bar) => DEEPSEEK_DSML_TOOL_KINDS.map((kind) => `</${bar}DSML${bar}${kind}>`));
2077
+ const DEEPSEEK_DSML_INVOKE_OPEN_PREFIXES = DEEPSEEK_DSML_BARS.map((bar) => `<${bar}DSML${bar}invoke`);
2078
+ const DEEPSEEK_DSML_INVOKE_CLOSE_TOKENS = DEEPSEEK_DSML_BARS.map((bar) => `</${bar}DSML${bar}invoke>`);
2466
2079
  const DEEPSEEK_DSML_TOOL_MAX_OPEN_TOKEN_LEN = Math.max(...DEEPSEEK_DSML_TOOL_OPEN_TOKENS.map((token) => token.length));
2080
+ 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));
2081
+ const MAX_DSML_RECOVERY_BUFFER_BYTES = 256e3;
2082
+ const DEEPSEEK_DSML_SCAN_BATCH_CHARS = 64 * 1024;
2467
2083
  function createDeepSeekDsmlToolCallRecoverer() {
2468
2084
  let buffer = "";
2085
+ let bufferBytes = 0;
2086
+ let bufferEndsWithHighSurrogate = false;
2087
+ let pendingScanChars = 0;
2088
+ let activeOpenToken = null;
2089
+ let blockScanState = {
2090
+ offset: 0,
2091
+ mode: "outer",
2092
+ invokeOpenStart: -1
2093
+ };
2094
+ const resetBlockScan = () => {
2095
+ activeOpenToken = null;
2096
+ pendingScanChars = 0;
2097
+ blockScanState = {
2098
+ offset: 0,
2099
+ mode: "outer",
2100
+ invokeOpenStart: -1
2101
+ };
2102
+ };
2469
2103
  const consume = (final) => {
2470
2104
  const output = [];
2471
2105
  while (buffer) {
2472
- const open = findEarliestStringToken(buffer, DEEPSEEK_DSML_TOOL_OPEN_TOKENS);
2106
+ const open = activeOpenToken ? {
2107
+ index: 0,
2108
+ token: activeOpenToken
2109
+ } : findEarliestStringToken(buffer, DEEPSEEK_DSML_TOOL_OPEN_TOKENS);
2473
2110
  if (!open) {
2111
+ resetBlockScan();
2474
2112
  if (final) {
2475
2113
  output.push({
2476
2114
  kind: "text",
2477
2115
  text: buffer
2478
2116
  });
2479
2117
  buffer = "";
2118
+ bufferBytes = 0;
2119
+ bufferEndsWithHighSurrogate = false;
2480
2120
  return output;
2481
2121
  }
2482
2122
  const keep = longestDeepSeekDsmlToolOpenPrefixSuffixLength(buffer);
2483
2123
  const emitLength = buffer.length - keep;
2484
2124
  if (emitLength > 0) {
2125
+ const emitted = buffer.slice(0, emitLength);
2485
2126
  output.push({
2486
2127
  kind: "text",
2487
- text: buffer.slice(0, emitLength)
2128
+ text: emitted
2488
2129
  });
2489
- buffer = buffer.slice(emitLength);
2130
+ bufferBytes -= Buffer.byteLength(emitted, "utf8");
2131
+ buffer = buffer.slice(emitted.length);
2132
+ if (!buffer) bufferEndsWithHighSurrogate = false;
2490
2133
  }
2491
2134
  return output;
2492
2135
  }
2493
2136
  if (open.index > 0) {
2137
+ const prefix = buffer.slice(0, open.index);
2494
2138
  output.push({
2495
2139
  kind: "text",
2496
- text: buffer.slice(0, open.index)
2140
+ text: prefix
2497
2141
  });
2498
- buffer = buffer.slice(open.index);
2142
+ bufferBytes -= Buffer.byteLength(prefix, "utf8");
2143
+ buffer = buffer.slice(prefix.length);
2144
+ resetBlockScan();
2499
2145
  }
2500
- const afterOpen = buffer.slice(open.token.length);
2501
- const close = findEarliestStringToken(afterOpen, DEEPSEEK_DSML_TOOL_CLOSE_TOKENS);
2146
+ activeOpenToken = open.token;
2147
+ if (blockScanState.offset === 0) blockScanState.offset = open.token.length;
2148
+ const blockScan = scanDeepSeekDsmlToolBlock(buffer, open.token.replace("<", "</"), open.token.length, blockScanState);
2149
+ if (blockScan.kind === "nested-open") throw new Error("Nested DeepSeek DSML recovery wrappers are not supported");
2150
+ const close = blockScan.kind === "close" ? blockScan : null;
2502
2151
  if (!close) {
2503
2152
  if (final) {
2504
2153
  output.push({
@@ -2506,24 +2155,38 @@ function createDeepSeekDsmlToolCallRecoverer() {
2506
2155
  text: buffer
2507
2156
  });
2508
2157
  buffer = "";
2158
+ bufferBytes = 0;
2159
+ bufferEndsWithHighSurrogate = false;
2160
+ return output;
2509
2161
  }
2162
+ if (bufferBytes > MAX_DSML_RECOVERY_BUFFER_BYTES) throw new Error("Exceeded DeepSeek DSML recovery buffer limit");
2510
2163
  return output;
2511
2164
  }
2512
- const body = afterOpen.slice(0, close.index);
2513
- const blockLength = open.token.length + close.index + close.token.length;
2165
+ resetBlockScan();
2166
+ const body = buffer.slice(open.token.length, close.index);
2167
+ const blockText = buffer.slice(0, close.index + close.token.length);
2168
+ if (Buffer.byteLength(blockText, "utf8") > MAX_DSML_RECOVERY_BUFFER_BYTES) throw new Error("Exceeded DeepSeek DSML recovery buffer limit");
2514
2169
  const recoveredToolCalls = parseDeepSeekDsmlToolCallBlock(body);
2515
2170
  if (recoveredToolCalls.length > 0) output.push(...recoveredToolCalls);
2516
2171
  else output.push({
2517
2172
  kind: "text",
2518
- text: buffer.slice(0, blockLength)
2173
+ text: blockText
2519
2174
  });
2520
- buffer = buffer.slice(blockLength);
2175
+ bufferBytes -= Buffer.byteLength(blockText, "utf8");
2176
+ buffer = buffer.slice(blockText.length);
2177
+ if (!buffer) bufferEndsWithHighSurrogate = false;
2521
2178
  }
2522
2179
  return output;
2523
2180
  };
2524
2181
  return {
2525
2182
  push(chunk) {
2183
+ const append = utf8ByteLengthForAppend(bufferEndsWithHighSurrogate, chunk);
2184
+ bufferBytes += append.bytes;
2185
+ bufferEndsWithHighSurrogate = append.endsWithHighSurrogate;
2526
2186
  buffer += chunk;
2187
+ pendingScanChars += chunk.length;
2188
+ if (activeOpenToken && pendingScanChars < DEEPSEEK_DSML_SCAN_BATCH_CHARS && !chunk.includes("<") && !chunk.includes(">") && bufferBytes <= MAX_DSML_RECOVERY_BUFFER_BYTES) return [];
2189
+ pendingScanChars = 0;
2527
2190
  return consume(false);
2528
2191
  },
2529
2192
  flush() {
@@ -2533,16 +2196,16 @@ function createDeepSeekDsmlToolCallRecoverer() {
2533
2196
  }
2534
2197
  function parseDeepSeekDsmlToolCallBlock(body) {
2535
2198
  const toolCalls = [];
2536
- const invokeOpenRegex = /<[||]DSML[||]invoke\b([^>]*)>/g;
2199
+ const invokeOpenRegex = /<[||]DSML[||]invoke\b([^<>]*)>/g;
2537
2200
  let openMatch;
2538
2201
  while ((openMatch = invokeOpenRegex.exec(body)) !== null) {
2539
- const invokeName = parseXmlAttribute(openMatch[1] ?? "", "name");
2540
- if (!invokeName) continue;
2541
2202
  const invokeBodyStart = openMatch.index + openMatch[0].length;
2542
2203
  const invokeClose = findEarliestStringToken(body.slice(invokeBodyStart), ["</|DSML|invoke>", "</|DSML|invoke>"]);
2543
- if (!invokeClose) continue;
2204
+ if (!invokeClose) break;
2544
2205
  const invokeBody = body.slice(invokeBodyStart, invokeBodyStart + invokeClose.index);
2545
2206
  invokeOpenRegex.lastIndex = invokeBodyStart + invokeClose.index + invokeClose.token.length;
2207
+ const invokeName = parseXmlAttribute(openMatch[1] ?? "", "name");
2208
+ if (!invokeName) continue;
2546
2209
  const parsedArguments = parseDeepSeekDsmlInvokeArguments(invokeBody);
2547
2210
  if (!parsedArguments) continue;
2548
2211
  toolCalls.push({
@@ -2593,10 +2256,10 @@ function parseXmlAttribute(attributes, name) {
2593
2256
  function decodeDeepSeekDsmlText(value) {
2594
2257
  return value.replaceAll("&quot;", "\"").replaceAll("&apos;", "'").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&");
2595
2258
  }
2596
- function findEarliestStringToken(text, tokens) {
2259
+ function findEarliestStringToken(text, tokens, fromIndex = 0) {
2597
2260
  let best = null;
2598
2261
  for (const token of tokens) {
2599
- const index = text.indexOf(token);
2262
+ const index = text.indexOf(token, fromIndex);
2600
2263
  if (index !== -1 && (!best || index < best.index)) best = {
2601
2264
  index,
2602
2265
  token
@@ -2604,6 +2267,89 @@ function findEarliestStringToken(text, tokens) {
2604
2267
  }
2605
2268
  return best;
2606
2269
  }
2270
+ function scanDeepSeekDsmlToolBlock(text, closeToken, contentStartIndex, state) {
2271
+ while (state.offset < text.length) {
2272
+ if (state.mode === "invoke-open") {
2273
+ const nextOpen = text.indexOf("<", state.offset);
2274
+ const nextClose = text.indexOf(">", state.offset);
2275
+ if (nextClose === -1 && nextOpen === -1) {
2276
+ state.offset = text.length;
2277
+ return { kind: "incomplete" };
2278
+ }
2279
+ if (nextOpen !== -1 && (nextClose === -1 || nextOpen < nextClose)) {
2280
+ state.mode = "outer";
2281
+ state.offset = nextOpen;
2282
+ state.invokeOpenStart = -1;
2283
+ continue;
2284
+ }
2285
+ const invokeOpenTag = text.slice(state.invokeOpenStart, nextClose + 1);
2286
+ if (!/^<[||]DSML[||]invoke\b[^<>]*>$/.test(invokeOpenTag)) {
2287
+ state.mode = "outer";
2288
+ state.offset = state.invokeOpenStart + 1;
2289
+ state.invokeOpenStart = -1;
2290
+ continue;
2291
+ }
2292
+ state.mode = "invoke-body";
2293
+ state.offset = nextClose + 1;
2294
+ state.invokeOpenStart = -1;
2295
+ continue;
2296
+ }
2297
+ if (state.mode === "invoke-body") {
2298
+ const invokeClose = findEarliestStringToken(text, DEEPSEEK_DSML_INVOKE_CLOSE_TOKENS, state.offset);
2299
+ if (!invokeClose) {
2300
+ state.offset = Math.max(0, text.length - DEEPSEEK_DSML_RECOVERY_MAX_BOUNDARY_LEN + 1);
2301
+ return { kind: "incomplete" };
2302
+ }
2303
+ state.mode = "outer";
2304
+ state.offset = invokeClose.index + invokeClose.token.length;
2305
+ continue;
2306
+ }
2307
+ const toolOpen = findEarliestStringToken(text, DEEPSEEK_DSML_TOOL_OPEN_TOKENS, state.offset);
2308
+ const toolCloseIndex = text.indexOf(closeToken, state.offset);
2309
+ const invokeOpen = findEarliestStringToken(text, DEEPSEEK_DSML_INVOKE_OPEN_PREFIXES, state.offset);
2310
+ const next = [
2311
+ toolOpen ? {
2312
+ kind: "nested-open",
2313
+ ...toolOpen
2314
+ } : null,
2315
+ toolCloseIndex === -1 ? null : {
2316
+ kind: "close",
2317
+ index: toolCloseIndex,
2318
+ token: closeToken
2319
+ },
2320
+ invokeOpen ? {
2321
+ kind: "invoke-open",
2322
+ ...invokeOpen
2323
+ } : null
2324
+ ].filter((candidate) => candidate !== null).toSorted((left, right) => left.index - right.index)[0];
2325
+ if (!next) {
2326
+ state.offset = Math.max(contentStartIndex, text.length - DEEPSEEK_DSML_RECOVERY_MAX_BOUNDARY_LEN + 1);
2327
+ return { kind: "incomplete" };
2328
+ }
2329
+ if (next.kind === "invoke-open") {
2330
+ state.mode = "invoke-open";
2331
+ state.invokeOpenStart = next.index;
2332
+ state.offset = next.index + next.token.length;
2333
+ continue;
2334
+ }
2335
+ return next;
2336
+ }
2337
+ return { kind: "incomplete" };
2338
+ }
2339
+ function utf8ByteLengthForAppend(bufferEndsWithHighSurrogate, chunk) {
2340
+ let bytes = Buffer.byteLength(chunk, "utf8");
2341
+ if (!chunk) return {
2342
+ bytes,
2343
+ endsWithHighSurrogate: bufferEndsWithHighSurrogate
2344
+ };
2345
+ const nextCodeUnit = chunk.charCodeAt(0);
2346
+ if (bufferEndsWithHighSurrogate && nextCodeUnit >= 56320 && nextCodeUnit <= 57343) bytes -= 2;
2347
+ const finalCodeUnit = chunk.charCodeAt(chunk.length - 1);
2348
+ return {
2349
+ bytes,
2350
+ endsWithHighSurrogate: finalCodeUnit >= 55296 && finalCodeUnit <= 56319
2351
+ };
2352
+ }
2607
2353
  function longestDeepSeekDsmlToolOpenPrefixSuffixLength(text) {
2608
2354
  const maxLength = Math.min(text.length, DEEPSEEK_DSML_TOOL_MAX_OPEN_TOKEN_LEN - 1);
2609
2355
  for (let length = maxLength; length > 0; length -= 1) {
@@ -2612,37 +2358,6 @@ function longestDeepSeekDsmlToolOpenPrefixSuffixLength(text) {
2612
2358
  }
2613
2359
  return 0;
2614
2360
  }
2615
- function getCompletionsContentDeltas(content) {
2616
- if (typeof content === "string") return content ? [{
2617
- kind: "text",
2618
- text: content
2619
- }] : [];
2620
- if (Array.isArray(content)) return content.flatMap((item) => getCompletionsContentDeltas(item));
2621
- if (!content || typeof content !== "object") return [];
2622
- const record = content;
2623
- const type = typeof record.type === "string" ? record.type.toLowerCase() : "";
2624
- const extractText = (value) => {
2625
- if (typeof value === "string") return value;
2626
- if (Array.isArray(value)) return value.map((item) => extractText(item)).join("");
2627
- if (value && typeof value === "object") {
2628
- const nested = value;
2629
- return extractText(nested.text ?? nested.content ?? nested.thinking);
2630
- }
2631
- return "";
2632
- };
2633
- const text = extractText(record.text ?? record.content ?? record.thinking);
2634
- if (!text) return [];
2635
- if (type.includes("thinking") || type.includes("reasoning")) return [{
2636
- kind: "thinking",
2637
- signature: "content",
2638
- text
2639
- }];
2640
- if (type === "text" || type === "output_text" || type.endsWith(".output_text")) return [{
2641
- kind: "text",
2642
- text
2643
- }];
2644
- return [];
2645
- }
2646
2361
  function getCompletionsReasoningDeltas(delta, visibleReasoningDetailTypes) {
2647
2362
  const output = [];
2648
2363
  const pushDelta = (next) => {
@@ -2795,10 +2510,6 @@ function resolveOpenAICompletionsEffectiveContextTokens(model) {
2795
2510
  function isQwenOpenAICompletionsThinkingFormat(format) {
2796
2511
  return format === "qwen" || format === "qwen-chat-template";
2797
2512
  }
2798
- function isOpenAICompletionsThinkingEnabled(effort) {
2799
- const normalized = effort.trim().toLowerCase();
2800
- return normalized !== "off" && normalized !== "none";
2801
- }
2802
2513
  function setQwenChatTemplateThinking(params, enabled) {
2803
2514
  const existing = params.chat_template_kwargs;
2804
2515
  params.chat_template_kwargs = existing && typeof existing === "object" && !Array.isArray(existing) ? {
@@ -3097,32 +2808,6 @@ function buildOpenAICompletionsParams(model, context, options) {
3097
2808
  else if (resolvedCompletionsReasoningEffort && model.reasoning && compat.supportsReasoningEffort && !handledQwenThinkingFormat && !omitChatCompletionsToolReasoningEffort) params.reasoning_effort = resolvedCompletionsReasoningEffort;
3098
2809
  return params;
3099
2810
  }
3100
- function parseTransportChunkUsage(rawUsage, model) {
3101
- const cacheWriteTokens = rawUsage.prompt_tokens_details?.cache_write_tokens || 0;
3102
- const cachedTokens = rawUsage.prompt_tokens_details?.cached_tokens || 0;
3103
- const promptTokens = rawUsage.prompt_tokens || 0;
3104
- const input = Math.max(0, promptTokens - cachedTokens - cacheWriteTokens);
3105
- const outputTokens = rawUsage.completion_tokens || 0;
3106
- const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens;
3107
- const usage = {
3108
- input,
3109
- output: outputTokens,
3110
- cacheRead: cachedTokens,
3111
- cacheWrite: cacheWriteTokens,
3112
- ...typeof reasoningTokens === "number" && Number.isFinite(reasoningTokens) ? { reasoningTokens } : {},
3113
- totalTokens: input + outputTokens + cachedTokens + cacheWriteTokens,
3114
- cost: {
3115
- input: 0,
3116
- output: 0,
3117
- cacheRead: 0,
3118
- cacheWrite: 0,
3119
- total: 0
3120
- }
3121
- };
3122
- calculateCost(model, usage);
3123
- applyProviderReportedUsageCost(usage, rawUsage.cost);
3124
- return usage;
3125
- }
3126
2811
  function hasOpenAICompletionsReasoningUsageActivity(rawUsage) {
3127
2812
  const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens;
3128
2813
  return typeof reasoningTokens === "number" && Number.isFinite(reasoningTokens) && reasoningTokens > 0;
@@ -3132,7 +2817,7 @@ const completionsTesting = {
3132
2817
  createSseDoneDetector,
3133
2818
  createOpenAICompletionsClient,
3134
2819
  buildOpenAICompletionsClientConfig,
3135
- parseTransportChunkUsage,
2820
+ parseTransportChunkUsage: parseOpenAICompletionsUsage,
3136
2821
  processOpenAICompletionsStream,
3137
2822
  shouldEmitOpenAICompletionsReasoningForModel
3138
2823
  };
@@ -3731,6 +3416,7 @@ function createResponsesTransportExecutor(config) {
3731
3416
  enforceCodeModeResponsesToolSurface(params, visibleToolNames);
3732
3417
  assertCodeModeResponsesToolSurface(params, visibleToolNames);
3733
3418
  }
3419
+ const observePrompt = createResponsesPromptEgressObserver(responsesOptions, context.systemPrompt);
3734
3420
  const requestStartedAt = Date.now();
3735
3421
  firstEventAbort = createFirstStreamEventAbortController(options?.signal);
3736
3422
  const requestOptions = buildOpenAISdkRequestOptions(model, firstEventAbort.signal, {
@@ -3739,12 +3425,17 @@ function createResponsesTransportExecutor(config) {
3739
3425
  maxRetries: options?.maxRetries
3740
3426
  });
3741
3427
  emitModelTransportDebug(log, `[responses] start provider=${model.provider} api=${model.api} model=${model.id} baseUrl=${formatModelTransportDebugBaseUrl(model.baseUrl)} timeoutMs=${safeDebugValue(requestOptions?.timeout)} apiKey=${apiKey ? "present" : "missing"} ${summarizeResponsesPayload(params)}`);
3742
- const responseStream = await config.createResponseStream({
3428
+ const { stream: responseStream, response } = await config.createResponseStream({
3743
3429
  client,
3744
3430
  request: params,
3745
3431
  requestOptions,
3746
- model
3432
+ model,
3433
+ observePrompt
3747
3434
  });
3435
+ await options?.onResponse?.({
3436
+ status: response.status,
3437
+ headers: headersToRecord(response.headers)
3438
+ }, model);
3748
3439
  emitModelTransportDebug(log, `[responses] headers provider=${model.provider} api=${model.api} model=${model.id} elapsedMs=${Date.now() - requestStartedAt}`);
3749
3440
  stream.push({
3750
3441
  type: "start",
@@ -3804,7 +3495,17 @@ function createAzureOpenAIResponsesTransportStreamFn() {
3804
3495
  firstEventTimeoutMs: AZURE_RESPONSES_FIRST_EVENT_TIMEOUT_MS,
3805
3496
  createClient: createAzureOpenAIClient,
3806
3497
  buildRequest: (model, context, options, metadata) => buildAzureOpenAIResponsesParams(model, context, options, resolveAzureDeploymentName(model), metadata),
3807
- createResponseStream: async ({ client, request, requestOptions }) => await client.responses.create(request, requestOptions)
3498
+ createResponseStream: async ({ client, request, requestOptions, observePrompt }) => {
3499
+ observePrompt?.(request, {
3500
+ egress: "responses-sdk",
3501
+ payloadVariant: "initial"
3502
+ });
3503
+ const { data, response } = await client.responses.create(request, requestOptions).withResponse();
3504
+ return {
3505
+ stream: data,
3506
+ response
3507
+ };
3508
+ }
3808
3509
  });
3809
3510
  }
3810
3511
  function normalizeAzureBaseUrl(baseUrl) {
@@ -3971,6 +3672,7 @@ function buildTransportAwareSimpleStreamFn(model, ctx) {
3971
3672
  //#endregion
3972
3673
  //#region packages/ai/src/transports/simple-completion-transport.ts
3973
3674
  const PROVIDER_SIMPLE_COMPLETION_API_PREFIX = "openclaw-provider-simple:";
3675
+ const PROVIDER_STREAM_API_PREFIX = "openclaw-provider-stream:";
3974
3676
  const INVALID_CODEX_BASE_URL_MESSAGE = "OpenAI Codex Responses baseUrl must not include query parameters or fragments";
3975
3677
  function registerCustomApi(registry, api, streamFn) {
3976
3678
  getAiTransportHost().registerCustomApi(registry, api, streamFn);
@@ -4023,6 +3725,15 @@ function resolveProviderSimpleCompletionApi(model) {
4023
3725
  ];
4024
3726
  return `${PROVIDER_SIMPLE_COMPLETION_API_PREFIX}${parts.map((part) => encodeURIComponent(part)).join(":")}`;
4025
3727
  }
3728
+ function resolveProviderStreamApi(model) {
3729
+ const parts = [
3730
+ model.provider,
3731
+ model.id,
3732
+ model.api,
3733
+ model.baseUrl || "default"
3734
+ ];
3735
+ return `${PROVIDER_STREAM_API_PREFIX}${parts.map((part) => encodeURIComponent(part)).join(":")}`;
3736
+ }
4026
3737
  function applyProviderSimpleCompletionWrapper(registry, model, cfg) {
4027
3738
  if (model.api.startsWith(PROVIDER_SIMPLE_COMPLETION_API_PREFIX)) return model;
4028
3739
  const sourceProvider = registry.getApiProvider(model.api);
@@ -4069,7 +3780,8 @@ function wrapPluginProviderStream(streamFn) {
4069
3780
  });
4070
3781
  };
4071
3782
  }
4072
- function registerProviderStreamForModel(params) {
3783
+ function prepareProviderStreamModel(params) {
3784
+ if (params.model.api === "google-generative-ai") return;
4073
3785
  const pluginModel = resolveModelHeaderSentinels(params.model);
4074
3786
  const providerStreamFn = getAiTransportHost().plugin.resolveProviderStream({
4075
3787
  provider: params.model.provider,
@@ -4083,15 +3795,19 @@ function registerProviderStreamForModel(params) {
4083
3795
  });
4084
3796
  const transportFallback = providerStreamFn ? void 0 : createTransportAwareStreamFnForModel(params.model.api === "google-generative-ai" ? pluginModel : params.model, { cfg: params.cfg });
4085
3797
  const streamFn = providerStreamFn ? wrapPluginProviderStream(providerStreamFn) : transportFallback && params.model.api === "google-generative-ai" ? wrapPluginProviderStream(transportFallback) : transportFallback;
4086
- return streamFn && registerCustomApi(params.apiRegistry, params.model.api, streamFn) ? streamFn : void 0;
3798
+ if (!streamFn) return;
3799
+ const api = params.apiRegistry.getApiProvider(params.model.api) ? resolveProviderStreamApi(params.model) : params.model.api;
3800
+ if (!registerCustomApi(params.apiRegistry, api, streamFn)) return;
3801
+ return api === params.model.api ? params.model : projectModel(params.model, { api });
4087
3802
  }
4088
3803
  function prepareModelForSimpleCompletion(params) {
4089
3804
  const { apiRegistry, model, cfg } = params;
4090
- if (!apiRegistry.getApiProvider(model.api) && registerProviderStreamForModel({
3805
+ const providerStreamModel = prepareProviderStreamModel({
4091
3806
  model,
4092
3807
  cfg,
4093
3808
  apiRegistry
4094
- })) return applyProviderSimpleCompletionWrapper(apiRegistry, model, cfg);
3809
+ });
3810
+ if (providerStreamModel) return applyProviderSimpleCompletionWrapper(apiRegistry, providerStreamModel, cfg);
4095
3811
  const codexTransportModel = prepareCodexSimpleTransportModel(apiRegistry, model, cfg);
4096
3812
  if (codexTransportModel) return applyProviderSimpleCompletionWrapper(apiRegistry, codexTransportModel, cfg);
4097
3813
  const transportAwareModel = prepareTransportAwareSimpleModel(model, { cfg });
@@ -4107,4 +3823,4 @@ function prepareModelForSimpleCompletion(params) {
4107
3823
  return applyProviderSimpleCompletionWrapper(apiRegistry, model, cfg);
4108
3824
  }
4109
3825
  //#endregion
4110
- export { GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, applyAnthropicEphemeralCacheControlMarkers, applyAnthropicPayloadPolicyToParams, applyOpenAIResponsesPayloadPolicy, assertCodeModeResponsesToolSurface, assignTransportErrorDetails, buildOpenAIClientHeaders, buildOpenAICompletionsParams, buildOpenAISdkClientOptions, buildOpenAISdkRequestOptions, buildTransportAwareSimpleStreamFn, canonicalizeMaxTokensParam, coerceTransportToolCallArguments, createAnthropicMessagesTransportStreamFn, createAzureOpenAIResponsesTransportStreamFn, createBoundaryAwareStreamFnForModel, createDeepSeekTextFilter, createEmptyTransportUsage, createModelStreamCooperativeScheduler, createOpenAICompletionsTransportStreamFn, createOpenAIResponsesTransportStreamFn, createOpenClawTransportStreamFnForModel, createTransportAwareStreamFnForModel, createWritableTransportEventStream, detectOpenAICompletionsCompat, emitModelTransportDebug, enforceCodeModeResponsesToolSurface, failTransportStream, filterCodeModePayloadTools, finalizeTransportStream, flattenCompletionMessagesToStringContent, formatModelTransportDebugBaseUrl, formatModelTransportDebugUrl, getCompat, hasOpenAICompatibleConversationTurn, isCodeModeModelVisibleToolName, isOpenAICodexResponsesModel, log, mergeTransportHeaders, mergeTransportMetadata, normalizeCodexResponsesBaseUrlForOpenAISdk, parseJsonObjectPreservingUnsafeIntegers, parseJsonPreservingUnsafeIntegers, prepareModelForSimpleCompletion, prepareTransportAwareSimpleModel, quoteUnsafeIntegerLiterals, readCodeModePayloadToolName, resolveAnthropicEphemeralCacheControl, resolveAnthropicMessagesUrl, resolveAnthropicPayloadPolicy, resolveCodeModeResponsesVisibleToolNames, resolveMaxTokensParam, resolveModelPayloadDebugMode, resolveModelSseDebugMode, resolveOpenAICompletionsCompat, resolveOpenAIReasoningEffortMap, resolveOpenAIResponsesPayloadPolicy, resolveOpenAIStrictToolFlagWithDiagnostics, resolvePromptCacheKey, resolveReplayableResponsesMessageId, resolveTransportAwareSimpleApi, sanitizeNonEmptyTransportPayloadText, sanitizeResponsesImagePayload, sanitizeTransportPayloadText, sortPromptCacheToolsByName as sortTransportToolsByName, stripCompletionMessagesToRoleContent, throwIfModelStreamAborted, transportAbortError, usesNativeOpenAICodexResponsesBackend };
3826
+ export { GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, applyAnthropicCacheControlToMessages, applyAnthropicEphemeralCacheControlMarkers, applyAnthropicPayloadPolicyToParams, applyOpenAIResponsesPayloadPolicy, assertCodeModeResponsesToolSurface, assignTransportErrorDetails, buildOpenAIClientHeaders, buildOpenAICompletionsParams, buildOpenAISdkClientOptions, buildOpenAISdkRequestOptions, buildTransportAwareSimpleStreamFn, canonicalizeMaxTokensParam, coerceTransportToolCallArguments, createAnthropicMessagesTransportStreamFn, createAzureOpenAIResponsesTransportStreamFn, createBoundaryAwareStreamFnForModel, createDeepSeekTextFilter, createEmptyTransportUsage, createModelStreamCooperativeScheduler, createOpenAICompletionsTransportStreamFn, createOpenAIResponsesTransportStreamFn, createOpenClawTransportStreamFnForModel, createTransportAwareStreamFnForModel, createWritableTransportEventStream, detectOpenAICompletionsCompat, emitModelTransportDebug, enforceCodeModeResponsesToolSurface, failTransportStream, filterCodeModePayloadTools, finalizeTransportStream, flattenCompletionMessagesToStringContent, formatModelTransportDebugBaseUrl, formatModelTransportDebugUrl, getCompat, hasOpenAICompatibleConversationTurn, isCodeModeModelVisibleToolName, isOpenAICodexResponsesModel, isOpenAICompletionsThinkingEnabled, log, mergeTransportHeaders, mergeTransportMetadata, normalizeCodexResponsesBaseUrlForOpenAISdk, parseJsonObjectPreservingUnsafeIntegers, parseJsonPreservingUnsafeIntegers, parseOpenAICompletionsUsage, prepareModelForSimpleCompletion, prepareTransportAwareSimpleModel, quoteUnsafeIntegerLiterals, readCodeModePayloadToolName, readOpenAICompletionsContentDeltas, resolveAnthropicEphemeralCacheControl, resolveAnthropicMessagesUrl, resolveAnthropicPayloadPolicy, resolveCodeModeResponsesVisibleToolNames, resolveMaxTokensParam, resolveModelPayloadDebugMode, resolveModelSseDebugMode, resolveOpenAICompletionsCompat, resolveOpenAIReasoningEffortMap, resolveOpenAIResponsesPayloadPolicy, resolveOpenAIStrictToolFlagWithDiagnostics, resolvePromptCacheKey, resolveReplayableResponsesMessageId, resolveTransportAwareSimpleApi, sanitizeNonEmptyTransportPayloadText, sanitizeResponsesImagePayload, sanitizeTransportPayloadText, sortPromptCacheToolsByName as sortTransportToolsByName, stripCompletionMessagesToRoleContent, throwIfModelStreamAborted, transportAbortError, usesNativeOpenAICodexResponsesBackend };