@openclaw/ai 2026.9.6 → 2026.9.8
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-DZQ_7gD1.mjs → anthropic-CTXJlfnS.mjs} +37 -66
- package/dist/{anthropic-payload-policy-DyfwikYJ.d.mts → anthropic-payload-policy-NIPVYXPq.d.mts} +7 -5
- package/dist/{anthropic-stream-reducer-D6ZI1wwj.mjs → anthropic-stream-reducer-DrsBCsFY.mjs} +192 -261
- package/dist/{api-registry-C2T3lTV7.d.mts → api-registry-D-nbmSqr.d.mts} +2 -2
- package/dist/{azure-openai-responses-DS86GYzq.mjs → azure-openai-responses-BBxv4QVI.mjs} +22 -33
- package/dist/{base64-CPmadnUf.mjs → base64-C1PsYcRQ.mjs} +15 -9
- package/dist/{diagnostics-CH8j2wIG.mjs → diagnostics-CJaB6g8J.mjs} +3 -3
- package/dist/diagnostics.d.mts +4 -4
- package/dist/diagnostics.mjs +2 -2
- package/dist/{env-api-keys-bktO00EJ.mjs → env-api-keys-CyX4VKGO.mjs} +7 -5
- package/dist/event-stream-CMQfX_yr.d.mts +1 -0
- package/dist/{event-stream-CjnIZZst.d.mts → event-stream-DOPFYVqs.d.mts} +2 -2
- package/dist/{event-stream-D8PARQfL.mjs → event-stream-vd9UnCAU.mjs} +10 -0
- package/dist/event-stream.d.mts +2 -2
- package/dist/event-stream.mjs +1 -1
- package/dist/{google-BZJFjhuC.mjs → google-B3HEK0Ag.mjs} +8 -11
- package/dist/google-interactions-vMlEfPAA.mjs +574 -0
- package/dist/{google-messages-DB7GKkDk.mjs → google-messages-Dz2dAnGo.mjs} +35 -71
- package/dist/{google-shared-Bok4I6zB.mjs → google-shared-B58i3c8H.mjs} +43 -47
- package/dist/{google-vertex-3eVNR2qW.mjs → google-vertex-DYFXzEbh.mjs} +16 -30
- package/dist/{host-yTvBrYM2.mjs → host-DwBmNMCC.mjs} +29 -188
- package/dist/{host-policy-DZO3oPPk.mjs → host-policy-wK-ay_RK.mjs} +2 -14
- package/dist/{host-DH-Z-LDb.d.mts → host-rxlNaBwm.d.mts} +9 -3
- package/dist/{index-C25RT6bP.d.mts → index-D6KsSE74.d.mts} +28 -8
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +6 -6
- package/dist/internal/anthropic.d.mts +8 -7
- package/dist/internal/anthropic.mjs +5 -5
- package/dist/internal/openai-completions-compat.d.mts +1 -1
- package/dist/internal/openai-completions-compat.mjs +1 -1
- package/dist/internal/openai-responses-payload-policy.d.mts +1 -1
- package/dist/internal/openai-responses-payload-policy.mjs +2 -2
- package/dist/internal/openai.d.mts +31 -8
- package/dist/internal/openai.mjs +13 -13
- package/dist/internal/runtime.d.mts +31 -70
- package/dist/internal/runtime.mjs +10 -65
- package/dist/internal/shared.d.mts +14 -12
- package/dist/internal/shared.mjs +5 -4
- package/dist/internal/tool-schema.d.mts +1 -1
- package/dist/internal/tool-schema.mjs +2 -2
- package/dist/{mistral-C_13dVBn.mjs → mistral-7wDWcjfF.mjs} +46 -93
- package/dist/{openai-chatgpt-responses-sTxPl4zM.mjs → openai-chatgpt-responses-Bc7NZrQR.mjs} +26 -30
- package/dist/{openai-completions-BO6D_hrB.mjs → openai-completions-CHnwIV-W.mjs} +14 -12
- package/dist/{openai-completions-compat-CUollwl6.mjs → openai-completions-compat-BJf57ZxN.mjs} +3 -5
- package/dist/{openai-completions-compat-DfJG1wSO.d.mts → openai-completions-compat-qJjmqQ71.d.mts} +3 -3
- package/dist/{openai-completions-stream-BpuJ0ZOA.mjs → openai-completions-stream-dju_5F3P.mjs} +101 -173
- package/dist/{openai-prompt-cache-CjV_2IRI.mjs → openai-prompt-cache-BTMs80_O.mjs} +1 -1
- package/dist/{openai-prompt-cache-C4RHdN4n.d.mts → openai-prompt-cache-CouErLh7.d.mts} +2 -2
- package/dist/{openai-provider-client-BP8J1aeg.mjs → openai-provider-client-G8Otsq2Q.mjs} +2 -2
- package/dist/{openai-reasoning-effort-ash8dPrd.mjs → openai-reasoning-effort-C_0p3psG.mjs} +5 -4
- package/dist/{openai-responses-BJ_IEoMU.mjs → openai-responses-DbPe3-Py.mjs} +12 -11
- package/dist/openai-responses-compaction-replay-DiYn-gFM.d.mts +12 -0
- package/dist/{openai-responses-compaction-window-BiNCT0bS.mjs → openai-responses-compaction-window-CYGCjAQz.mjs} +5 -5
- package/dist/{openai-responses-contracts-DWrfMODE.mjs → openai-responses-contracts-CLxnqS9p.mjs} +1 -1
- package/dist/{openai-responses-contracts-B1ENJFpI.d.mts → openai-responses-contracts-D1iZ0njF.d.mts} +4 -4
- package/dist/{openai-responses-prompt-observer-internal-DPHWgbBH.mjs → openai-responses-prompt-observer-internal-BX3QTNSv.mjs} +12 -12
- package/dist/{openai-responses-request-lifecycle-DFuyO1pQ.mjs → openai-responses-request-lifecycle-Fsag-IGZ.mjs} +1 -1
- package/dist/{openai-responses-shared-DvSqtJ6_.mjs → openai-responses-shared-CIEHiKx7.mjs} +312 -122
- package/dist/{openai-responses-terminal-usage-BNFbvY9f.d.mts → openai-responses-terminal-usage-BE7lf7nW.d.mts} +2 -2
- package/dist/{openai-stop-reason-Drnn_6Qj.mjs → openai-stop-reason-8s70vDXj.mjs} +2 -12
- package/dist/{openai-tool-schema-ynZBgqW-.d.mts → openai-tool-schema-a5ysBBga.d.mts} +0 -6
- package/dist/{openai-tool-schema-D4BMcj2D.mjs → openai-tool-schema-vsl-cE-n.mjs} +243 -383
- package/dist/{openai-transport-params-DZKOTSfH.mjs → openai-transport-params-DyFJ4cgR.mjs} +60 -105
- package/dist/{positive-integer-BiUxrd71.mjs → positive-integer-CjN5OJbH.mjs} +1 -1
- package/dist/{provider-error-CRhW7lkJ.mjs → provider-error-CwT_j2v0.mjs} +43 -4
- package/dist/{provider-options-DZYq53lj.d.mts → provider-options-Df7ov0K1.d.mts} +2 -2
- package/dist/{provider-replay-context-DPr3w20a.mjs → provider-replay-context-Bs5aWE1d.mjs} +1 -1
- package/dist/{provider-transcript-transform-BTocjCRs.mjs → provider-transcript-transform-DjA5Fk2P.mjs} +17 -2
- package/dist/{provider-transport-turn-state-lrXEFkYr.mjs → provider-transport-turn-state-Dw7OtYUs.mjs} +1 -1
- package/dist/{provider-types-w1rEqrGP.d.mts → provider-types-d4XnoZMd.d.mts} +3 -3
- package/dist/provider-types.d.mts +6 -6
- package/dist/providers.d.mts +2 -2
- package/dist/providers.mjs +15 -11
- package/dist/{reasoning-tag-text-partitioner-Di38crhI.mjs → reasoning-tag-text-partitioner-B6FIIBt6.mjs} +47 -71
- package/dist/{record-coerce-DwRYMj3t.mjs → record-coerce-CNDovvft.mjs} +1 -1
- package/dist/simple-options-BkDPMuxw.mjs +349 -0
- package/dist/{src-DwGYYyZp.mjs → src-H4aXcFuX.mjs} +43 -25
- package/dist/{stream-CREqxHgU.mjs → stream-DDsCBgd-.mjs} +1 -7
- package/dist/{stream-first-event-timeout-BeptfRL6.mjs → stream-first-event-timeout-B9o0S4SZ.mjs} +1 -1
- package/dist/{tool-schema-json-projection-CD9c_fK8.mjs → tool-schema-json-projection-Ct8SeBeJ.mjs} +63 -23
- package/dist/{transport-stream-shared-B5RioB_Q.mjs → transport-stream-shared-BU5pwY6W.mjs} +62 -28
- package/dist/{transport-stream-shared-B7Z9oCYg.d.mts → transport-stream-shared-yYhXa4kX.d.mts} +12 -6
- package/dist/{transport-utils-03Qi0CN2.mjs → transport-utils-CqXzku3R.mjs} +3 -4
- package/dist/transports.d.mts +36 -32
- package/dist/transports.mjs +160 -216
- package/dist/types-CB-_vNyI.d.mts +1 -0
- package/dist/{types-qZFbaDbK.d.mts → types-CLLR3eB4.d.mts} +3 -1
- package/dist/types.d.mts +6 -6
- package/dist/types.mjs +4 -4
- package/dist/{validation-Dw7cb6BV.mjs → validation-BFZc40Ig.mjs} +80 -54
- package/dist/{validation-DhQhmt6t.d.mts → validation-Cat2wQsc.d.mts} +1 -1
- package/dist/validation.d.mts +1 -1
- package/dist/validation.mjs +1 -1
- package/package.json +5 -5
- package/dist/assistant-output-DM1JBNs1.mjs +0 -16
- package/dist/event-stream-C0nsgbj2.d.mts +0 -1
- package/dist/simple-options-np1XPuhm.mjs +0 -175
- package/dist/types-DTvddOfm.d.mts +0 -1
- package/dist/utf16-slice-CvGodqok.mjs +0 -29
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { r as appendAssistantThinking } from "./event-stream-
|
|
2
|
-
import {
|
|
3
|
-
import { v as
|
|
4
|
-
import {
|
|
1
|
+
import { r as appendAssistantThinking } from "./event-stream-vd9UnCAU.mjs";
|
|
2
|
+
import { k as isImageWithMediaPayload, w as calculateCost } from "./host-DwBmNMCC.mjs";
|
|
3
|
+
import { a as createEmptyTransportUsage, b as transportAbortError, j as sanitizeSurrogates, r as coerceTransportToolCallArguments, v as sanitizeTransportPayloadText } from "./transport-stream-shared-BU5pwY6W.mjs";
|
|
4
|
+
import { D as sortPromptCacheToolsByName, d as describeToolResultMediaPlaceholder, m as extractToolResultText } from "./simple-options-BkDPMuxw.mjs";
|
|
5
5
|
import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
|
|
6
6
|
//#region packages/ai/src/transports/google-thinking-level.ts
|
|
7
7
|
/** Returns whether a Gemini Flash model accepts the MINIMAL thinking level. */
|
|
@@ -66,16 +66,10 @@ async function consumeGoogleGenerateContentStream(params) {
|
|
|
66
66
|
const blockIndex = () => blocks.length - 1;
|
|
67
67
|
const endCurrentBlock = () => {
|
|
68
68
|
if (!currentBlock) return;
|
|
69
|
-
|
|
70
|
-
type: "text_end",
|
|
69
|
+
params.stream.push({
|
|
70
|
+
type: currentBlock.type === "text" ? "text_end" : "thinking_end",
|
|
71
71
|
contentIndex: blockIndex(),
|
|
72
|
-
content: currentBlock.text,
|
|
73
|
-
partial: params.output
|
|
74
|
-
});
|
|
75
|
-
else params.stream.push({
|
|
76
|
-
type: "thinking_end",
|
|
77
|
-
contentIndex: blockIndex(),
|
|
78
|
-
content: currentBlock.thinking,
|
|
72
|
+
content: currentBlock.type === "text" ? currentBlock.text : currentBlock.thinking,
|
|
79
73
|
partial: params.output
|
|
80
74
|
});
|
|
81
75
|
currentBlock = null;
|
|
@@ -101,18 +95,11 @@ async function consumeGoogleGenerateContentStream(params) {
|
|
|
101
95
|
const toolUsePromptTokens = knownUsage.toolUsePromptTokenCount;
|
|
102
96
|
const outputTokens = knownUsage.candidatesTokenCount + knownUsage.thoughtsTokenCount;
|
|
103
97
|
params.output.usage = {
|
|
98
|
+
...createEmptyTransportUsage(),
|
|
104
99
|
input: Math.max(0, promptTokens - cacheRead) + toolUsePromptTokens,
|
|
105
100
|
output: outputTokens,
|
|
106
101
|
cacheRead,
|
|
107
|
-
|
|
108
|
-
totalTokens: chunk.usageMetadata.totalTokenCount ?? promptTokens + outputTokens + toolUsePromptTokens,
|
|
109
|
-
cost: {
|
|
110
|
-
input: 0,
|
|
111
|
-
output: 0,
|
|
112
|
-
cacheRead: 0,
|
|
113
|
-
cacheWrite: 0,
|
|
114
|
-
total: 0
|
|
115
|
-
}
|
|
102
|
+
totalTokens: chunk.usageMetadata.totalTokenCount ?? promptTokens + outputTokens + toolUsePromptTokens
|
|
116
103
|
};
|
|
117
104
|
calculateCost(params.model, params.output.usage);
|
|
118
105
|
}
|
|
@@ -153,51 +140,35 @@ async function consumeGoogleGenerateContentStream(params) {
|
|
|
153
140
|
const isThinking = part.thought === true || !preserveParts && !hasText;
|
|
154
141
|
if (!currentBlock || isThinking && currentBlock.type !== "thinking" || !isThinking && currentBlock.type !== "text") {
|
|
155
142
|
endCurrentBlock();
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
type: "text",
|
|
171
|
-
text: ""
|
|
172
|
-
};
|
|
173
|
-
params.output.content.push(currentBlock);
|
|
174
|
-
params.stream.push({
|
|
175
|
-
type: "text_start",
|
|
176
|
-
contentIndex: blockIndex(),
|
|
177
|
-
partial: params.output
|
|
178
|
-
});
|
|
179
|
-
}
|
|
143
|
+
currentBlock = isThinking ? {
|
|
144
|
+
type: "thinking",
|
|
145
|
+
thinking: "",
|
|
146
|
+
...preserveParts ? { thinkingSignature: void 0 } : {}
|
|
147
|
+
} : {
|
|
148
|
+
type: "text",
|
|
149
|
+
text: ""
|
|
150
|
+
};
|
|
151
|
+
params.output.content.push(currentBlock);
|
|
152
|
+
params.stream.push({
|
|
153
|
+
type: isThinking ? "thinking_start" : "text_start",
|
|
154
|
+
contentIndex: blockIndex(),
|
|
155
|
+
partial: params.output
|
|
156
|
+
});
|
|
180
157
|
}
|
|
181
158
|
const delta = hasText ? text : "";
|
|
182
159
|
if (currentBlock.type === "thinking") {
|
|
183
160
|
appendAssistantThinking(currentBlock, delta);
|
|
184
161
|
currentBlock.thinkingSignature = retainThoughtSignature(currentBlock.thinkingSignature, part.thoughtSignature);
|
|
185
|
-
params.stream.push({
|
|
186
|
-
type: "thinking_delta",
|
|
187
|
-
contentIndex: blockIndex(),
|
|
188
|
-
delta,
|
|
189
|
-
partial: params.output
|
|
190
|
-
});
|
|
191
162
|
} else {
|
|
192
163
|
currentBlock.text += delta;
|
|
193
164
|
currentBlock.textSignature = retainThoughtSignature(currentBlock.textSignature, part.thoughtSignature);
|
|
194
|
-
params.stream.push({
|
|
195
|
-
type: "text_delta",
|
|
196
|
-
contentIndex: blockIndex(),
|
|
197
|
-
delta,
|
|
198
|
-
partial: params.output
|
|
199
|
-
});
|
|
200
165
|
}
|
|
166
|
+
params.stream.push({
|
|
167
|
+
type: currentBlock.type === "thinking" ? "thinking_delta" : "text_delta",
|
|
168
|
+
contentIndex: blockIndex(),
|
|
169
|
+
delta,
|
|
170
|
+
partial: params.output
|
|
171
|
+
});
|
|
201
172
|
if (signatureOnly) endCurrentBlock();
|
|
202
173
|
}
|
|
203
174
|
if (part.functionCall) {
|
|
@@ -352,22 +323,15 @@ function projectGoogleMessages(params) {
|
|
|
352
323
|
let sawFunctionCall = false;
|
|
353
324
|
const nextReplaySignatures = /* @__PURE__ */ new Map();
|
|
354
325
|
const isSameProviderAndModel = msg.provider === model.provider && msg.api === model.api && msg.model === model.id;
|
|
355
|
-
for (const block of msg.content) if (block.type === "text") {
|
|
356
|
-
const
|
|
357
|
-
|
|
326
|
+
for (const block of msg.content) if (block.type === "text" || block.type === "thinking") {
|
|
327
|
+
const text = block.type === "text" ? block.text : block.thinking;
|
|
328
|
+
const thoughtSignature = isSameProviderAndModel ? signature(block.type === "text" ? block.textSignature : block.thinkingSignature) : void 0;
|
|
329
|
+
if ((!text || text.trim() === "") && (managed || !thoughtSignature)) continue;
|
|
358
330
|
parts.push({
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
});
|
|
362
|
-
} else if (block.type === "thinking") {
|
|
363
|
-
const thoughtSignature = isSameProviderAndModel ? signature(block.thinkingSignature) : void 0;
|
|
364
|
-
if ((!block.thinking || block.thinking.trim() === "") && (managed || !thoughtSignature)) continue;
|
|
365
|
-
if (isSameProviderAndModel) parts.push({
|
|
366
|
-
thought: true,
|
|
367
|
-
text: sanitizeText(block.thinking),
|
|
331
|
+
...block.type === "thinking" && isSameProviderAndModel ? { thought: true } : {},
|
|
332
|
+
text: sanitizeText(text),
|
|
368
333
|
...thoughtSignature && { thoughtSignature }
|
|
369
334
|
});
|
|
370
|
-
else parts.push({ text: sanitizeText(block.thinking) });
|
|
371
335
|
} else if (block.type === "toolCall") {
|
|
372
336
|
if (isSameProviderAndModel && (managed || model.provider !== "google-gemini-cli")) sameRouteToolCallIds.add(block.id);
|
|
373
337
|
const args = coerceTransportToolCallArguments(block.arguments);
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { t as
|
|
1
|
+
import { T as clampThinkingLevel } from "./host-DwBmNMCC.mjs";
|
|
2
|
+
import { b as transportAbortError, c as failTransportStream, h as notifyProviderStreamOpened, j as sanitizeSurrogates } from "./transport-stream-shared-BU5pwY6W.mjs";
|
|
3
|
+
import { C as stripSystemPromptCacheBoundary } from "./simple-options-BkDPMuxw.mjs";
|
|
4
|
+
import { t as transformProviderMessages } from "./provider-transcript-transform-DjA5Fk2P.mjs";
|
|
5
|
+
import { a as googleFlashSupportsMinimalThinking, i as consumeGoogleGenerateContentStream, n as projectGoogleMessages, r as requiresGoogleToolCallId, t as convertGoogleTools } from "./google-messages-Dz2dAnGo.mjs";
|
|
6
6
|
import { FunctionCallingConfigMode, ThinkingLevel } from "@google/genai";
|
|
7
7
|
//#region packages/ai/src/providers/google-shared.ts
|
|
8
|
-
/**
|
|
9
|
-
* Shared utilities for Google Generative AI and Google Vertex providers.
|
|
10
|
-
*/
|
|
11
8
|
function convertMessages(model, context) {
|
|
12
9
|
return projectGoogleMessages({
|
|
13
10
|
model,
|
|
@@ -53,23 +50,20 @@ async function runGoogleGenerateContentLifecycle(params) {
|
|
|
53
50
|
} catch (error) {
|
|
54
51
|
for (const block of output.content) if ("index" in block) delete block.index;
|
|
55
52
|
const failure = options?.signal?.aborted ? transportAbortError(options.signal) : error;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
53
|
+
failTransportStream({
|
|
54
|
+
stream,
|
|
55
|
+
output,
|
|
56
|
+
error: failure,
|
|
57
|
+
signal: options?.signal
|
|
61
58
|
});
|
|
62
|
-
stream.end();
|
|
63
59
|
}
|
|
64
60
|
}
|
|
65
61
|
function buildGoogleGenerateContentParams(model, context, options = {}) {
|
|
66
62
|
const contents = convertMessages(model, context);
|
|
67
|
-
const generationConfig = {};
|
|
68
|
-
if (options.temperature !== void 0) generationConfig.temperature = options.temperature;
|
|
69
|
-
if (options.maxTokens !== void 0) generationConfig.maxOutputTokens = options.maxTokens;
|
|
70
|
-
if (options.stop !== void 0 && options.stop.length > 0) generationConfig.stopSequences = options.stop;
|
|
71
63
|
const config = {
|
|
72
|
-
...
|
|
64
|
+
...options.temperature !== void 0 && { temperature: options.temperature },
|
|
65
|
+
...options.maxTokens !== void 0 && { maxOutputTokens: options.maxTokens },
|
|
66
|
+
...options.stop !== void 0 && options.stop.length > 0 && { stopSequences: options.stop },
|
|
73
67
|
...context.systemPrompt && { systemInstruction: sanitizeSurrogates(stripSystemPromptCacheBoundary(context.systemPrompt)) },
|
|
74
68
|
...context.tools && context.tools.length > 0 && { tools: convertGoogleTools(context.tools) }
|
|
75
69
|
};
|
|
@@ -122,6 +116,28 @@ function buildGoogleSimpleThinking(model, options) {
|
|
|
122
116
|
budgetTokens: getGoogleBudget(model, effort, options.thinkingBudgets)
|
|
123
117
|
};
|
|
124
118
|
}
|
|
119
|
+
function buildGoogleInteractionsSimpleThinking(model, options) {
|
|
120
|
+
const thinking = buildGoogleSimpleThinking(model, options);
|
|
121
|
+
if (!thinking.enabled) {
|
|
122
|
+
if (!model.reasoning) return thinking;
|
|
123
|
+
const disabled = getDisabledGoogleThinkingConfig(model);
|
|
124
|
+
return {
|
|
125
|
+
enabled: false,
|
|
126
|
+
...disabled.thinkingLevel ? { level: disabled.thinkingLevel } : {}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
if (thinking.level !== void 0 || !options?.reasoning || isAdaptiveGoogleReasoningLevel(options.reasoning)) return thinking;
|
|
130
|
+
const clampedReasoning = clampThinkingLevel(model, options.reasoning);
|
|
131
|
+
if (clampedReasoning === "off") return { enabled: false };
|
|
132
|
+
if (clampedReasoning === "xhigh" || clampedReasoning === "max") return {
|
|
133
|
+
enabled: true,
|
|
134
|
+
level: getGoogleThinkingLevel("high", model)
|
|
135
|
+
};
|
|
136
|
+
return {
|
|
137
|
+
enabled: true,
|
|
138
|
+
level: getGoogleThinkingLevel(clampedReasoning, model)
|
|
139
|
+
};
|
|
140
|
+
}
|
|
125
141
|
function getDisabledGoogleThinkingConfig(model) {
|
|
126
142
|
if (isGemini3ProModel(model)) return { thinkingLevel: ThinkingLevel.LOW };
|
|
127
143
|
if (isGemini3FlashModel(model)) return { thinkingLevel: googleFlashSupportsMinimalThinking(model.id) ? ThinkingLevel.MINIMAL : ThinkingLevel.LOW };
|
|
@@ -139,18 +155,9 @@ function isGemini3FlashModel(model) {
|
|
|
139
155
|
return /gemini-(?:3(?:\.\d+)?-flash|flash(?:-lite)?-latest)/.test(model.id.toLowerCase());
|
|
140
156
|
}
|
|
141
157
|
function getGoogleThinkingLevel(effort, model) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
case "medium":
|
|
146
|
-
case "high": return ThinkingLevel.HIGH;
|
|
147
|
-
}
|
|
148
|
-
if (isGemma4Model(model)) switch (effort) {
|
|
149
|
-
case "minimal":
|
|
150
|
-
case "low": return ThinkingLevel.MINIMAL;
|
|
151
|
-
case "medium":
|
|
152
|
-
case "high": return ThinkingLevel.HIGH;
|
|
153
|
-
}
|
|
158
|
+
const lowEffort = effort === "minimal" || effort === "low";
|
|
159
|
+
if (isGemini3ProModel(model)) return lowEffort ? ThinkingLevel.LOW : ThinkingLevel.HIGH;
|
|
160
|
+
if (isGemma4Model(model)) return lowEffort ? ThinkingLevel.MINIMAL : ThinkingLevel.HIGH;
|
|
154
161
|
switch (effort) {
|
|
155
162
|
case "minimal": return isGemini3FlashModel(model) && !googleFlashSupportsMinimalThinking(model.id) ? ThinkingLevel.LOW : ThinkingLevel.MINIMAL;
|
|
156
163
|
case "low": return ThinkingLevel.LOW;
|
|
@@ -161,25 +168,14 @@ function getGoogleThinkingLevel(effort, model) {
|
|
|
161
168
|
}
|
|
162
169
|
function getGoogleBudget(model, effort, customBudgets) {
|
|
163
170
|
if (customBudgets?.[effort] !== void 0) return customBudgets[effort];
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
medium: 8192,
|
|
168
|
-
high: 32768
|
|
169
|
-
}[effort];
|
|
170
|
-
if (model.id.includes("2.5-flash-lite")) return {
|
|
171
|
-
minimal: 512,
|
|
172
|
-
low: 2048,
|
|
173
|
-
medium: 8192,
|
|
174
|
-
high: 24576
|
|
175
|
-
}[effort];
|
|
176
|
-
if (model.id.includes("2.5-flash")) return {
|
|
177
|
-
minimal: 128,
|
|
171
|
+
const isPro = model.id.includes("2.5-pro");
|
|
172
|
+
if (isPro || model.id.includes("2.5-flash")) return {
|
|
173
|
+
minimal: !isPro && model.id.includes("2.5-flash-lite") ? 512 : 128,
|
|
178
174
|
low: 2048,
|
|
179
175
|
medium: 8192,
|
|
180
|
-
high: 24576
|
|
176
|
+
high: isPro ? 32768 : 24576
|
|
181
177
|
}[effort];
|
|
182
178
|
return -1;
|
|
183
179
|
}
|
|
184
180
|
//#endregion
|
|
185
|
-
export {
|
|
181
|
+
export { runGoogleGenerateContentLifecycle as i, buildGoogleInteractionsSimpleThinking as n, buildGoogleSimpleThinking as r, buildGoogleGenerateContentParams as t };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { t as AssistantMessageEventStream } from "./event-stream-
|
|
1
|
+
import { t as AssistantMessageEventStream } from "./event-stream-vd9UnCAU.mjs";
|
|
2
|
+
import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-DwBmNMCC.mjs";
|
|
2
3
|
import { a as normalizeOptionalString } from "./string-coerce-fsri9iCu.mjs";
|
|
3
|
-
import { n as
|
|
4
|
-
import { n as
|
|
5
|
-
import { t as
|
|
6
|
-
import { n as buildGoogleSimpleThinking, r as runGoogleGenerateContentLifecycle, t as buildGoogleGenerateContentParams } from "./google-shared-Bok4I6zB.mjs";
|
|
4
|
+
import { n as buildBaseOptions } from "./simple-options-BkDPMuxw.mjs";
|
|
5
|
+
import { n as createAssistantOutput } from "./provider-transcript-transform-DjA5Fk2P.mjs";
|
|
6
|
+
import { i as runGoogleGenerateContentLifecycle, r as buildGoogleSimpleThinking, t as buildGoogleGenerateContentParams } from "./google-shared-B58i3c8H.mjs";
|
|
7
7
|
import { GoogleGenAI, ResourceScope } from "@google/genai";
|
|
8
8
|
//#region packages/ai/src/providers/google-vertex.ts
|
|
9
9
|
const API_VERSION = "v1";
|
|
@@ -17,11 +17,8 @@ const streamGoogleVertex = (model, context, options) => {
|
|
|
17
17
|
model,
|
|
18
18
|
output,
|
|
19
19
|
options,
|
|
20
|
-
createClient: () =>
|
|
21
|
-
|
|
22
|
-
return apiKey ? createClientWithApiKey(model, apiKey, options?.headers) : createClient(model, resolveProject(options), resolveLocation(options), options?.headers);
|
|
23
|
-
},
|
|
24
|
-
buildParams: () => buildParams(model, context, options),
|
|
20
|
+
createClient: () => createClient(model, options),
|
|
21
|
+
buildParams: () => buildGoogleGenerateContentParams(model, context, options),
|
|
25
22
|
nextToolCallId: (name) => `${name}_${Date.now()}_${++toolCallCounter}`
|
|
26
23
|
});
|
|
27
24
|
return stream;
|
|
@@ -33,22 +30,17 @@ const streamSimpleGoogleVertex = (model, context, options) => {
|
|
|
33
30
|
thinking: buildGoogleSimpleThinking(model, options)
|
|
34
31
|
});
|
|
35
32
|
};
|
|
36
|
-
function createClient(model,
|
|
33
|
+
function createClient(model, options) {
|
|
34
|
+
const apiKey = resolveApiKey(options);
|
|
35
|
+
const credentials = apiKey ? { apiKey: getAiTransportHost().resolveSecretSentinel(apiKey) } : {
|
|
36
|
+
project: resolveProject(options),
|
|
37
|
+
location: resolveLocation(options)
|
|
38
|
+
};
|
|
37
39
|
return new GoogleGenAI({
|
|
38
40
|
vertexai: true,
|
|
39
|
-
|
|
40
|
-
location,
|
|
41
|
+
...credentials,
|
|
41
42
|
apiVersion: API_VERSION,
|
|
42
|
-
httpOptions: buildHttpOptions(model,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
function createClientWithApiKey(model, apiKey, optionsHeaders) {
|
|
46
|
-
const resolvedApiKey = getAiTransportHost().resolveSecretSentinel(apiKey);
|
|
47
|
-
return new GoogleGenAI({
|
|
48
|
-
vertexai: true,
|
|
49
|
-
apiKey: resolvedApiKey,
|
|
50
|
-
apiVersion: API_VERSION,
|
|
51
|
-
httpOptions: buildHttpOptions(model, optionsHeaders)
|
|
43
|
+
httpOptions: buildHttpOptions(model, options?.headers)
|
|
52
44
|
});
|
|
53
45
|
}
|
|
54
46
|
function buildHttpOptions(model, optionsHeaders) {
|
|
@@ -79,12 +71,9 @@ function baseUrlIncludesApiVersion(baseUrl) {
|
|
|
79
71
|
}
|
|
80
72
|
function resolveApiKey(options) {
|
|
81
73
|
const apiKey = options?.apiKey?.trim() || process.env.GOOGLE_CLOUD_API_KEY?.trim();
|
|
82
|
-
if (!apiKey || apiKey === GCP_VERTEX_CREDENTIALS_MARKER ||
|
|
74
|
+
if (!apiKey || apiKey === GCP_VERTEX_CREDENTIALS_MARKER || /^<[^>]+>$/.test(apiKey)) return;
|
|
83
75
|
return apiKey;
|
|
84
76
|
}
|
|
85
|
-
function isPlaceholderApiKey(apiKey) {
|
|
86
|
-
return /^<[^>]+>$/.test(apiKey);
|
|
87
|
-
}
|
|
88
77
|
function resolveProject(options) {
|
|
89
78
|
const project = normalizeOptionalString(options?.project) || normalizeOptionalString(process.env.GOOGLE_CLOUD_PROJECT) || normalizeOptionalString(process.env.GCLOUD_PROJECT);
|
|
90
79
|
if (!project) throw new Error("Vertex AI requires a project ID. Set GOOGLE_CLOUD_PROJECT/GCLOUD_PROJECT or pass project in options.");
|
|
@@ -95,8 +84,5 @@ function resolveLocation(options) {
|
|
|
95
84
|
if (!location) throw new Error("Vertex AI requires a location. Set GOOGLE_CLOUD_LOCATION or pass location in options.");
|
|
96
85
|
return location;
|
|
97
86
|
}
|
|
98
|
-
function buildParams(model, context, options = {}) {
|
|
99
|
-
return buildGoogleGenerateContentParams(model, context, options);
|
|
100
|
-
}
|
|
101
87
|
//#endregion
|
|
102
88
|
export { streamGoogleVertex, streamSimpleGoogleVertex };
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { T as supportsClaudeNativeXhighEffort, _ as resolveClaudeOpus55ModelIdentity, a as CLAUDE_OPUS_55_THINKING_PROFILE, b as resolveClaudeSonnet5ModelIdentity, d as requiresClaudeDefaultSampling, f as requiresClaudeMandatoryAdaptiveThinking, g as resolveClaudeNativeThinkingLevelMap, h as resolveClaudeMythos5ModelIdentity, i as CLAUDE_FABLE_5_THINKING_PROFILE, p as resolveClaudeFable5ModelIdentity, s as CLAUDE_SONNET_55_THINKING_PROFILE, t as calculateUsageCost, v as resolveClaudeOpus5ModelIdentity, w as supportsClaudeNativeMaxEffort, y as resolveClaudeSonnet55ModelIdentity } from "./src-H4aXcFuX.mjs";
|
|
2
|
+
import { i as asOptionalRecord, o as isRecord } from "./record-coerce-CNDovvft.mjs";
|
|
2
3
|
import { n as normalizeLowercaseStringOrEmpty } from "./string-coerce-fsri9iCu.mjs";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import { f as MODEL_CATALOG_THINKING_LEVELS, m as resolveOpenAIThinkingApi, o as resolveOpenAIModelReasoningEfforts, p as listMappedModelThinkingLevels } from "./openai-reasoning-effort-C_0p3psG.mjs";
|
|
5
|
+
//#region packages/ai/src/media-payload.ts
|
|
6
|
+
/** Media metadata alone is not an attachment; provider emitters need inline bytes. */
|
|
7
|
+
function hasMediaPayload(block) {
|
|
8
|
+
return isRecord(block) && typeof block.data === "string" && block.data.trim().length > 0;
|
|
9
|
+
}
|
|
10
|
+
/** Image metadata alone is not an attachment; provider emitters need inline bytes. */
|
|
11
|
+
function isImageWithMediaPayload(block) {
|
|
12
|
+
return isRecord(block) && block.type === "image" && hasMediaPayload(block);
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
6
15
|
//#region packages/ai/src/model-utils.ts
|
|
7
16
|
/** Calculates and stores model cost fields from token usage and per-million pricing. */
|
|
8
17
|
function calculateCost(model, usage) {
|
|
@@ -59,7 +68,7 @@ function headersToRecord(headers) {
|
|
|
59
68
|
}
|
|
60
69
|
//#endregion
|
|
61
70
|
//#region packages/ai/src/providers/anthropic-model-contract.ts
|
|
62
|
-
const ANTHROPIC_CLAUDE_CODE_VERSION = "2.1.
|
|
71
|
+
const ANTHROPIC_CLAUDE_CODE_VERSION = "2.1.280";
|
|
63
72
|
/** Build OAuth headers and the matching billing identity from one request snapshot. */
|
|
64
73
|
function buildAnthropicClaudeCodeIdentity(betaHeader, ...headerSources) {
|
|
65
74
|
const headers = new Headers({
|
|
@@ -115,7 +124,7 @@ function defaultsClaudeAdaptiveThinking(model) {
|
|
|
115
124
|
}
|
|
116
125
|
/** Resolve provider-native effort once for direct and managed Claude requests. */
|
|
117
126
|
function resolveAnthropicThinkingEffort(model, level) {
|
|
118
|
-
const requestedLevel = level ?? (resolveClaudeOpus55ModelIdentity(model) ? CLAUDE_OPUS_55_THINKING_PROFILE.defaultLevel : resolveClaudeFable5ModelIdentity(model) ? CLAUDE_FABLE_5_THINKING_PROFILE.defaultLevel : void 0);
|
|
127
|
+
const requestedLevel = level ?? (resolveClaudeOpus55ModelIdentity(model) ? CLAUDE_OPUS_55_THINKING_PROFILE.defaultLevel : resolveClaudeSonnet55ModelIdentity(model) ? CLAUDE_SONNET_55_THINKING_PROFILE.defaultLevel : resolveClaudeFable5ModelIdentity(model) ? CLAUDE_FABLE_5_THINKING_PROFILE.defaultLevel : void 0);
|
|
119
128
|
const thinkingLevelMap = resolveClaudeNativeThinkingLevelMap(model);
|
|
120
129
|
const clampModel = {
|
|
121
130
|
...model,
|
|
@@ -189,15 +198,20 @@ function resolveReplayModelBoundIdentity(ref) {
|
|
|
189
198
|
const sonnetIdentity = resolveClaudeSonnet5ModelIdentity(modelRef);
|
|
190
199
|
return sonnetIdentity ? `sonnet:${sonnetIdentity}` : void 0;
|
|
191
200
|
}
|
|
201
|
+
const FABLE_51_REPLAY_IDENTITY = /^fable:claude-fable-5-1(?=$|[^a-z0-9])/;
|
|
202
|
+
const SONNET_55_REPLAY_IDENTITY = /^sonnet:claude-sonnet-5-5(?=$|[^a-z0-9])/;
|
|
192
203
|
/**
|
|
193
|
-
* Fable 5.1 reads
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
* every other cross-identity move
|
|
197
|
-
*
|
|
204
|
+
* Verified live (2026-09-28): Fable 5.1 reads every earlier Claude generation
|
|
205
|
+
* except Sonnet 5.5; Sonnet 5.5 reads Sonnet 5 and pre-Claude-5 thinking but
|
|
206
|
+
* not Opus 5, Fable, or Mythos; no other model reads Sonnet 5.5 thinking. The
|
|
207
|
+
* API drops what a target cannot read, and every other cross-identity move
|
|
208
|
+
* stays dropped here until its replay contract is proven separately.
|
|
198
209
|
*/
|
|
199
|
-
function readsPriorClaudeThinking(targetIdentity) {
|
|
200
|
-
|
|
210
|
+
function readsPriorClaudeThinking(targetIdentity, sourceIdentity) {
|
|
211
|
+
if (targetIdentity === void 0) return false;
|
|
212
|
+
if (FABLE_51_REPLAY_IDENTITY.test(targetIdentity)) return sourceIdentity === void 0 || !SONNET_55_REPLAY_IDENTITY.test(sourceIdentity);
|
|
213
|
+
if (SONNET_55_REPLAY_IDENTITY.test(targetIdentity)) return sourceIdentity === void 0 || sourceIdentity.startsWith("sonnet:");
|
|
214
|
+
return false;
|
|
201
215
|
}
|
|
202
216
|
function isClaudeReplaySource(ref) {
|
|
203
217
|
const modelId = hasConcreteResponseModel(ref) ? ref.responseModelId : ref.modelId;
|
|
@@ -210,184 +224,11 @@ function resolveModelBoundThinkingReplayMode(params) {
|
|
|
210
224
|
const targetIdentity = resolveReplayModelBoundIdentity(params.target);
|
|
211
225
|
const sameRoute = normalizeLowercaseStringOrEmpty(params.source.provider) === normalizeLowercaseStringOrEmpty(params.target.provider) && sourceApi === targetApi && normalizeModelId(params.source.modelId) === normalizeModelId(params.target.modelId);
|
|
212
226
|
if (!sourceIdentity && !targetIdentity) return "default";
|
|
213
|
-
if (sourceApi === targetApi && readsPriorClaudeThinking(targetIdentity) && isClaudeReplaySource(params.source)) return "preserve";
|
|
227
|
+
if (sourceApi === targetApi && readsPriorClaudeThinking(targetIdentity, sourceIdentity) && isClaudeReplaySource(params.source)) return "preserve";
|
|
214
228
|
if (!sourceIdentity && !hasConcreteResponseModel(params.source) && targetIdentity && sameRoute) return "preserve";
|
|
215
229
|
return sourceApi === targetApi && sourceIdentity === targetIdentity ? "preserve" : "drop";
|
|
216
230
|
}
|
|
217
231
|
//#endregion
|
|
218
|
-
//#region packages/ai/src/utils/sanitize-unicode.ts
|
|
219
|
-
/**
|
|
220
|
-
* Removes unpaired Unicode surrogate characters from a string.
|
|
221
|
-
*
|
|
222
|
-
* Unpaired surrogates (high surrogates 0xD800-0xDBFF without matching low surrogates 0xDC00-0xDFFF,
|
|
223
|
-
* or vice versa) cause JSON serialization errors in many API providers.
|
|
224
|
-
*
|
|
225
|
-
* Valid emoji and other characters outside the Basic Multilingual Plane use properly paired
|
|
226
|
-
* surrogates and will NOT be affected by this function.
|
|
227
|
-
*
|
|
228
|
-
* @param text - The text to sanitize
|
|
229
|
-
* @returns The sanitized text with unpaired surrogates removed
|
|
230
|
-
*
|
|
231
|
-
* @example
|
|
232
|
-
* // Valid emoji (properly paired surrogates) are preserved
|
|
233
|
-
* sanitizeSurrogates("Hello 🙈 World") // => "Hello 🙈 World"
|
|
234
|
-
*
|
|
235
|
-
* // Unpaired high surrogate is removed
|
|
236
|
-
* const unpaired = String.fromCharCode(0xD83D); // high surrogate without low
|
|
237
|
-
* sanitizeSurrogates(`Text ${unpaired} here`) // => "Text here"
|
|
238
|
-
*/
|
|
239
|
-
function sanitizeSurrogates(text) {
|
|
240
|
-
if (text.isWellFormed()) return text;
|
|
241
|
-
return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
|
|
242
|
-
}
|
|
243
|
-
//#endregion
|
|
244
|
-
//#region packages/ai/src/providers/tool-result-text.ts
|
|
245
|
-
const STRUCTURED_TOOL_RESULT_MAX_CHARS = 8e3;
|
|
246
|
-
const IMAGE_TOOL_RESULT_TYPES = /* @__PURE__ */ new Set([
|
|
247
|
-
"image",
|
|
248
|
-
"image_url",
|
|
249
|
-
"input_image"
|
|
250
|
-
]);
|
|
251
|
-
const AUDIO_TOOL_RESULT_TYPES = /* @__PURE__ */ new Set([
|
|
252
|
-
"audio",
|
|
253
|
-
"input_audio",
|
|
254
|
-
"output_audio"
|
|
255
|
-
]);
|
|
256
|
-
const MEDIA_ONLY_TOOL_RESULT_TYPES = /* @__PURE__ */ new Set([...IMAGE_TOOL_RESULT_TYPES, ...AUDIO_TOOL_RESULT_TYPES]);
|
|
257
|
-
const INLINE_DATA_URI_PATTERN = /(^|[^A-Za-z0-9_])data:([a-z][a-z0-9.+-]*\/[a-z0-9.+-]+(?:;[a-z0-9.+-]+=[^,;"'\s]+|;base64)*,[^\s"'<>)]+)/gi;
|
|
258
|
-
const MIME_KEY_CANDIDATES = [
|
|
259
|
-
"mimeType",
|
|
260
|
-
"mime_type",
|
|
261
|
-
"mediaType",
|
|
262
|
-
"media_type",
|
|
263
|
-
"contentType",
|
|
264
|
-
"content_type"
|
|
265
|
-
];
|
|
266
|
-
const TEXTUAL_MIME_PATTERN = /^(?:text\/|application\/(?:json|ld\+json|x-ndjson|xml|javascript|x-www-form-urlencoded)|[^/]+\/[^+]+\+(?:json|xml)$)/i;
|
|
267
|
-
const OPAQUE_OR_BINARY_FIELD_RE = /^(?:blob|buffer|bytes|encrypted_content|encrypted_stdout)$/i;
|
|
268
|
-
function readMimeType(value) {
|
|
269
|
-
if (!isRecord(value)) return;
|
|
270
|
-
for (const key of MIME_KEY_CANDIDATES) {
|
|
271
|
-
const mimeType = value[key];
|
|
272
|
-
if (typeof mimeType === "string" && mimeType.trim().length > 0) return mimeType;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
function isBinaryMimeType(mimeType) {
|
|
276
|
-
const normalized = mimeType.split(";", 1)[0]?.trim().toLowerCase();
|
|
277
|
-
return normalized ? !TEXTUAL_MIME_PATTERN.test(normalized) : false;
|
|
278
|
-
}
|
|
279
|
-
function describeOmittedValue(value, label) {
|
|
280
|
-
const length = typeof value === "string" ? value.length : JSON.stringify(value)?.length;
|
|
281
|
-
return length ? `[${label} omitted: ${length} chars]` : `[${label} omitted]`;
|
|
282
|
-
}
|
|
283
|
-
function redactInlineDataUris(value) {
|
|
284
|
-
return value.replace(INLINE_DATA_URI_PATTERN, (_match, prefix, uri) => `${prefix}[inline data URI: ${uri.length} chars]`);
|
|
285
|
-
}
|
|
286
|
-
function stringifyStructuredBlock(block) {
|
|
287
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
288
|
-
try {
|
|
289
|
-
const host = getAiTransportHost();
|
|
290
|
-
const redactedBlock = host.redactModelVisibleSecrets({ structuredToolResult: block }).structuredToolResult;
|
|
291
|
-
const serialized = JSON.stringify(redactedBlock, function structuredToolResultReplacer(key, value) {
|
|
292
|
-
if (OPAQUE_OR_BINARY_FIELD_RE.test(key)) return `[omitted ${key}]`;
|
|
293
|
-
if (key === "data") {
|
|
294
|
-
const mimeType = readMimeType(this);
|
|
295
|
-
if (mimeType && isBinaryMimeType(mimeType)) return describeOmittedValue(value, "binary data");
|
|
296
|
-
}
|
|
297
|
-
if (typeof value === "bigint") return value.toString();
|
|
298
|
-
if (typeof value === "string") return redactInlineDataUris(host.redactModelVisibleSecrets(value));
|
|
299
|
-
if (typeof value === "function" || typeof value === "symbol" || value === void 0) return;
|
|
300
|
-
if (!value || typeof value !== "object") return value;
|
|
301
|
-
if (seen.has(value)) return "[Circular]";
|
|
302
|
-
seen.add(value);
|
|
303
|
-
return value;
|
|
304
|
-
});
|
|
305
|
-
if (!serialized || serialized === "{}") return;
|
|
306
|
-
return serialized;
|
|
307
|
-
} catch {
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
function truncateStructuredToolText(text) {
|
|
312
|
-
if (text.length <= STRUCTURED_TOOL_RESULT_MAX_CHARS) return text;
|
|
313
|
-
return `${truncateUtf16Safe(text, STRUCTURED_TOOL_RESULT_MAX_CHARS)}\n…(truncated)…`;
|
|
314
|
-
}
|
|
315
|
-
/** Media metadata alone is not an attachment; provider emitters need inline bytes. */
|
|
316
|
-
function hasMediaPayload(block) {
|
|
317
|
-
return isRecord(block) && typeof block.data === "string" && block.data.trim().length > 0;
|
|
318
|
-
}
|
|
319
|
-
/** Image metadata alone is not an attachment; provider emitters need inline bytes. */
|
|
320
|
-
function isImageWithMediaPayload(block) {
|
|
321
|
-
return isRecord(block) && block.type === "image" && hasMediaPayload(block);
|
|
322
|
-
}
|
|
323
|
-
function classifyToolResultMedia(blocks) {
|
|
324
|
-
let hasImage = false;
|
|
325
|
-
let hasAudio = false;
|
|
326
|
-
for (const block of blocks) {
|
|
327
|
-
if (!hasMediaPayload(block) || block.type === "text") continue;
|
|
328
|
-
const type = typeof block.type === "string" ? block.type : void 0;
|
|
329
|
-
const mimeType = readMimeType(block)?.toLowerCase();
|
|
330
|
-
hasImage ||= Boolean(type && IMAGE_TOOL_RESULT_TYPES.has(type) || mimeType?.startsWith("image/"));
|
|
331
|
-
hasAudio ||= Boolean(type && AUDIO_TOOL_RESULT_TYPES.has(type) || mimeType?.startsWith("audio/"));
|
|
332
|
-
}
|
|
333
|
-
return {
|
|
334
|
-
hasImage,
|
|
335
|
-
hasAudio
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
function describeToolResultMediaPlaceholder(blocks) {
|
|
339
|
-
const { hasImage, hasAudio } = classifyToolResultMedia(blocks);
|
|
340
|
-
if (hasImage && hasAudio) return "(see attached media)";
|
|
341
|
-
if (hasAudio) return "(see attached audio)";
|
|
342
|
-
return hasImage ? "(see attached image)" : void 0;
|
|
343
|
-
}
|
|
344
|
-
function extractToolResultBlockText(block) {
|
|
345
|
-
if (!block || typeof block !== "object") return;
|
|
346
|
-
const record = block;
|
|
347
|
-
if (typeof record.type === "string" && MEDIA_ONLY_TOOL_RESULT_TYPES.has(record.type)) return;
|
|
348
|
-
if (record.type === "text") {
|
|
349
|
-
const text = typeof record.text === "string" ? record.text : "";
|
|
350
|
-
return text ? sanitizeSurrogates(text) : void 0;
|
|
351
|
-
}
|
|
352
|
-
const structured = stringifyStructuredBlock(record);
|
|
353
|
-
return structured ? sanitizeSurrogates(truncateStructuredToolText(structured)) : void 0;
|
|
354
|
-
}
|
|
355
|
-
function extractToolResultText(blocks, options) {
|
|
356
|
-
const explicitTexts = [];
|
|
357
|
-
const structuredBlocks = [];
|
|
358
|
-
for (const block of blocks) {
|
|
359
|
-
if (!block || typeof block !== "object") continue;
|
|
360
|
-
if (block.type === "text") {
|
|
361
|
-
const text = extractToolResultBlockText(block);
|
|
362
|
-
if (text) explicitTexts.push(text);
|
|
363
|
-
} else structuredBlocks.push(block);
|
|
364
|
-
}
|
|
365
|
-
if (explicitTexts.length > 0 && !options?.includeStructured) return explicitTexts.join("\n");
|
|
366
|
-
const structuredTexts = [];
|
|
367
|
-
for (const block of structuredBlocks) {
|
|
368
|
-
const text = extractToolResultBlockText(block);
|
|
369
|
-
if (text) structuredTexts.push(text);
|
|
370
|
-
}
|
|
371
|
-
if (explicitTexts.length > 0) {
|
|
372
|
-
if (structuredTexts.length > 0) explicitTexts.push(truncateStructuredToolText(structuredTexts.join("\n")));
|
|
373
|
-
return explicitTexts.join("\n");
|
|
374
|
-
}
|
|
375
|
-
return truncateStructuredToolText(structuredTexts.join("\n"));
|
|
376
|
-
}
|
|
377
|
-
/** Describe media that cannot be represented on the target provider wire. */
|
|
378
|
-
function describeUnsupportedToolResultMedia(blocks, support) {
|
|
379
|
-
const { hasImage, hasAudio } = classifyToolResultMedia(blocks);
|
|
380
|
-
const omittedImage = hasImage && !support.images;
|
|
381
|
-
const omittedAudio = hasAudio && !support.audio;
|
|
382
|
-
if (omittedImage && omittedAudio) return "[unsupported tool-result media omitted]";
|
|
383
|
-
if (omittedAudio) return "[unsupported tool-result audio omitted]";
|
|
384
|
-
return omittedImage ? "[unsupported tool-result image omitted]" : void 0;
|
|
385
|
-
}
|
|
386
|
-
function formatToolResultText(params) {
|
|
387
|
-
const body = params.text.trim() ? `${params.text}${params.omittedMediaPlaceholder ? `\n${params.omittedMediaPlaceholder}` : ""}` : params.omittedMediaPlaceholder ?? params.mediaPlaceholder ?? "(no tool output)";
|
|
388
|
-
return `${params.isError ? "[tool error] " : ""}${body}`;
|
|
389
|
-
}
|
|
390
|
-
//#endregion
|
|
391
232
|
//#region packages/ai/src/replay-turn-classification.ts
|
|
392
233
|
/** Returns true when an assistant turn contains only provider reasoning and blank text. */
|
|
393
234
|
function hasOnlyAssistantReasoningContent(message) {
|
|
@@ -687,4 +528,4 @@ function resolveAiTransportHeaderSentinels(headers) {
|
|
|
687
528
|
return resolvedHeaders ?? headers;
|
|
688
529
|
}
|
|
689
530
|
//#endregion
|
|
690
|
-
export {
|
|
531
|
+
export { applyProviderReportedUsageCost as C, modelsAreEqual as D, getSupportedThinkingLevels as E, hasMediaPayload as O, headersToRecord as S, clampThinkingLevel as T, requiresClaudeAdaptiveThinking as _, FAILED_ASSISTANT_REPLAY_TEXT as a, usesClaudeFable5MessagesContract as b, isReasoningOnlyLengthAssistantTurn as c, ANTHROPIC_CLAUDE_CODE_VERSION as d, applyClaudeRequestContract as f, prepareClaudeNoPrefillRequestContext as g, mapAnthropicStopReason as h, transformMessages as i, isImageWithMediaPayload as k, isStreamErrorFallbackContent as l, defaultsClaudeAdaptiveThinking as m, getAiTransportHost as n, STREAM_ERROR_FALLBACK_TEXT as o, buildAnthropicClaudeCodeIdentity as p, resolveAiTransportHeaderSentinels as r, hasOnlyAssistantReasoningContent as s, configureAiTransportHost as t, resolveFailedAssistantReplay as u, resolveAnthropicThinkingEffort as v, calculateCost as w, usesClaudeStreamingRefusalContract as x, resolveModelBoundThinkingReplayMode as y };
|