@openclaw/ai 0.0.0 → 2026.7.1-beta.4

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 (64) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +27 -3
  3. package/dist/anthropic-B5gZQM5X.mjs +1383 -0
  4. package/dist/api-registry-COYU2fF4.d.mts +33 -0
  5. package/dist/azure-openai-responses-CkxVwqPL.mjs +141 -0
  6. package/dist/azure-openai-responses-client-compat-a_O_GVQV.mjs +41 -0
  7. package/dist/diagnostics-BaTA9eVl.d.mts +25 -0
  8. package/dist/diagnostics-COpOtRwq.mjs +36 -0
  9. package/dist/diagnostics.d.mts +2 -0
  10. package/dist/diagnostics.mjs +2 -0
  11. package/dist/env-api-keys-CtMlqaQ4.mjs +171 -0
  12. package/dist/event-stream-C-T9juXb.d.mts +26 -0
  13. package/dist/event-stream-ReMmOTzX.mjs +65 -0
  14. package/dist/event-stream.d.mts +2 -0
  15. package/dist/event-stream.mjs +2 -0
  16. package/dist/github-copilot-headers-BsH5cqGj.mjs +48 -0
  17. package/dist/google-D6sIQ1bL.mjs +55 -0
  18. package/dist/google-shared-ZPSl2qTi.mjs +548 -0
  19. package/dist/google-vertex-rDGwkoZK.mjs +111 -0
  20. package/dist/hash-CHgqbJmD.mjs +16 -0
  21. package/dist/headers-B_e4-1J0.mjs +9 -0
  22. package/dist/host-4t713IeR.mjs +37 -0
  23. package/dist/index-BoTnz8cv.d.mts +74 -0
  24. package/dist/index.d.mts +69 -0
  25. package/dist/index.mjs +7 -0
  26. package/dist/internal/anthropic.d.mts +234 -0
  27. package/dist/internal/anthropic.mjs +4 -0
  28. package/dist/internal/openai.d.mts +242 -0
  29. package/dist/internal/openai.mjs +7 -0
  30. package/dist/internal/runtime.d.mts +245 -0
  31. package/dist/internal/runtime.mjs +176 -0
  32. package/dist/internal/shared.d.mts +48 -0
  33. package/dist/internal/shared.mjs +3 -0
  34. package/dist/json-parse-DzNSIQBq.mjs +134 -0
  35. package/dist/llm-request-activity-CehVkZP-.mjs +35 -0
  36. package/dist/mistral-CePVNdws.mjs +563 -0
  37. package/dist/model-utils-DgmOla96.mjs +69 -0
  38. package/dist/openai-chatgpt-jwt-DhAAzLkj.mjs +39 -0
  39. package/dist/openai-chatgpt-responses-CYqFzw4W.mjs +1068 -0
  40. package/dist/openai-completions-IOlOeB-u.mjs +841 -0
  41. package/dist/openai-responses-CKTUdtu9.mjs +136 -0
  42. package/dist/openai-responses-shared-CO5L7re5.mjs +1936 -0
  43. package/dist/openai-tool-projection-BknoV11q.mjs +195 -0
  44. package/dist/providers.d.mts +11 -0
  45. package/dist/providers.mjs +109 -0
  46. package/dist/reasoning-tag-text-partitioner-axhAdUwg.mjs +394 -0
  47. package/dist/sanitize-unicode-BZiVbGwK.d.mts +24 -0
  48. package/dist/sanitize-unicode-DT5o51ur.mjs +26 -0
  49. package/dist/src-CZ503MYJ.mjs +99 -0
  50. package/dist/stream-CREqxHgU.mjs +74 -0
  51. package/dist/stream-first-event-timeout-RjWszj8c.mjs +106 -0
  52. package/dist/streaming-byte-guard-BrbkbwUu.mjs +46 -0
  53. package/dist/tool-schema-json-projection-BXtBc_mD.mjs +74 -0
  54. package/dist/transform-messages-BhGF_fF4.mjs +507 -0
  55. package/dist/types-BVVgDSdq.d.mts +1 -0
  56. package/dist/types-DZAZItYw.d.mts +585 -0
  57. package/dist/types.d.mts +6 -0
  58. package/dist/types.mjs +5 -0
  59. package/dist/validation-Ctw0PWEu.d.mts +9 -0
  60. package/dist/validation-FrchoOlv.mjs +199 -0
  61. package/dist/validation.d.mts +2 -0
  62. package/dist/validation.mjs +2 -0
  63. package/npm-shrinkwrap.json +645 -0
  64. package/package.json +75 -3
@@ -0,0 +1,548 @@
1
+ import { n as calculateCost, r as clampThinkingLevel } from "./model-utils-DgmOla96.mjs";
2
+ import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
3
+ import { b as stripSystemPromptCacheBoundary, i as extractToolResultText, n as describeToolResultMediaPlaceholder, t as transformMessages } from "./transform-messages-BhGF_fF4.mjs";
4
+ import { FinishReason, FunctionCallingConfigMode } from "@google/genai";
5
+ //#region packages/ai/src/providers/google-shared.ts
6
+ /**
7
+ * Shared utilities for Google Generative AI and Google Vertex providers.
8
+ */
9
+ /**
10
+ * Determines whether a streamed Gemini `Part` should be treated as "thinking".
11
+ *
12
+ * Protocol note (Gemini / Vertex AI thought signatures):
13
+ * - `thought: true` is the definitive marker for thinking content (thought summaries).
14
+ * - `thoughtSignature` is an encrypted representation of the model's internal thought process
15
+ * used to preserve reasoning context across multi-turn interactions.
16
+ * - `thoughtSignature` can appear on ANY part type (text, functionCall, etc.) - it does NOT
17
+ * indicate the part itself is thinking content.
18
+ * - For non-functionCall responses, the signature appears on the last part for context replay.
19
+ * - When persisting/replaying model outputs, signature-bearing parts must be preserved as-is;
20
+ * do not merge/move signatures across parts.
21
+ *
22
+ * See: https://ai.google.dev/gemini-api/docs/thought-signatures
23
+ */
24
+ function isThinkingPart(part) {
25
+ return part.thought === true;
26
+ }
27
+ /**
28
+ * Retain thought signatures during streaming.
29
+ *
30
+ * Some backends only send `thoughtSignature` on the first delta for a given part/block; later deltas may omit it.
31
+ * This helper preserves the last non-empty signature for the current block.
32
+ *
33
+ * Note: this does NOT merge or move signatures across distinct response parts. It only prevents
34
+ * a signature from being overwritten with `undefined` within the same streamed block.
35
+ */
36
+ function retainThoughtSignature(existing, incoming) {
37
+ if (typeof incoming === "string" && incoming.length > 0) return incoming;
38
+ return existing;
39
+ }
40
+ const base64SignaturePattern = /^[A-Za-z0-9+/]+={0,2}$/;
41
+ function isValidThoughtSignature(signature) {
42
+ if (!signature) return false;
43
+ if (signature.length % 4 !== 0) return false;
44
+ return base64SignaturePattern.test(signature);
45
+ }
46
+ /**
47
+ * Only keep signatures from the same provider/model and with valid base64.
48
+ */
49
+ function resolveThoughtSignature(isSameProviderAndModel, signature) {
50
+ return isSameProviderAndModel && isValidThoughtSignature(signature) ? signature : void 0;
51
+ }
52
+ /**
53
+ * Models via Google APIs that require explicit tool call IDs in function calls/responses.
54
+ */
55
+ function requiresToolCallId(modelId) {
56
+ return modelId.startsWith("claude-") || modelId.startsWith("gpt-oss-");
57
+ }
58
+ function getGeminiMajorVersion(modelId) {
59
+ const match = modelId.toLowerCase().match(/^gemini(?:-live)?-(\d+)/);
60
+ if (!match) return;
61
+ return Number.parseInt(match[1], 10);
62
+ }
63
+ function supportsMultimodalFunctionResponse(modelId) {
64
+ const geminiMajorVersion = getGeminiMajorVersion(modelId);
65
+ if (geminiMajorVersion !== void 0) return geminiMajorVersion >= 3;
66
+ return true;
67
+ }
68
+ /**
69
+ * Convert internal messages to Gemini Content[] format.
70
+ */
71
+ function convertMessages(model, context) {
72
+ const contents = [];
73
+ const normalizeToolCallId = (id) => {
74
+ if (!requiresToolCallId(model.id)) return id;
75
+ return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
76
+ };
77
+ const transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);
78
+ const pendingToolResultImageTurns = [];
79
+ let activeToolResultParts;
80
+ const flushToolResultRun = () => {
81
+ contents.push(...pendingToolResultImageTurns);
82
+ pendingToolResultImageTurns.length = 0;
83
+ activeToolResultParts = void 0;
84
+ };
85
+ for (const msg of transformedMessages) {
86
+ if (msg.role !== "toolResult") flushToolResultRun();
87
+ if (msg.role === "user") if (typeof msg.content === "string") contents.push({
88
+ role: "user",
89
+ parts: [{ text: sanitizeSurrogates(msg.content) }]
90
+ });
91
+ else {
92
+ const parts = msg.content.map((item) => {
93
+ if (item.type === "text") return { text: sanitizeSurrogates(item.text) };
94
+ return { inlineData: {
95
+ mimeType: item.mimeType,
96
+ data: item.data
97
+ } };
98
+ });
99
+ if (parts.length === 0) continue;
100
+ contents.push({
101
+ role: "user",
102
+ parts
103
+ });
104
+ }
105
+ else if (msg.role === "assistant") {
106
+ const parts = [];
107
+ const isSameProviderAndModel = msg.provider === model.provider && msg.model === model.id;
108
+ for (const block of msg.content) if (block.type === "text") {
109
+ if (!block.text || block.text.trim() === "") continue;
110
+ const thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.textSignature);
111
+ parts.push({
112
+ text: sanitizeSurrogates(block.text),
113
+ ...thoughtSignature && { thoughtSignature }
114
+ });
115
+ } else if (block.type === "thinking") {
116
+ if (!block.thinking || block.thinking.trim() === "") continue;
117
+ if (isSameProviderAndModel) {
118
+ const thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.thinkingSignature);
119
+ parts.push({
120
+ thought: true,
121
+ text: sanitizeSurrogates(block.thinking),
122
+ ...thoughtSignature && { thoughtSignature }
123
+ });
124
+ } else parts.push({ text: sanitizeSurrogates(block.thinking) });
125
+ } else if (block.type === "toolCall") {
126
+ const thoughtSignature = resolveThoughtSignature(isSameProviderAndModel, block.thoughtSignature);
127
+ const part = {
128
+ functionCall: {
129
+ name: block.name,
130
+ args: block.arguments ?? {},
131
+ ...requiresToolCallId(model.id) ? { id: block.id } : {}
132
+ },
133
+ ...thoughtSignature && { thoughtSignature }
134
+ };
135
+ parts.push(part);
136
+ }
137
+ if (parts.length === 0) continue;
138
+ contents.push({
139
+ role: "model",
140
+ parts
141
+ });
142
+ } else if (msg.role === "toolResult") {
143
+ const textResult = extractToolResultText(msg.content);
144
+ const imageContent = model.input.includes("image") ? msg.content.filter((c) => c.type === "image") : [];
145
+ const hasText = textResult.length > 0;
146
+ const hasImages = imageContent.length > 0;
147
+ const mediaPlaceholder = describeToolResultMediaPlaceholder(msg.content);
148
+ const modelSupportsMultimodalFunctionResponse = supportsMultimodalFunctionResponse(model.id);
149
+ const responseValue = hasText ? sanitizeSurrogates(textResult) : mediaPlaceholder ?? "";
150
+ const imageParts = imageContent.map((imageBlock) => ({ inlineData: {
151
+ mimeType: imageBlock.mimeType,
152
+ data: imageBlock.data
153
+ } }));
154
+ const includeId = requiresToolCallId(model.id);
155
+ const functionResponsePart = { functionResponse: {
156
+ name: msg.toolName,
157
+ response: msg.isError ? { error: responseValue } : { output: responseValue },
158
+ ...hasImages && modelSupportsMultimodalFunctionResponse && { parts: imageParts },
159
+ ...includeId ? { id: msg.toolCallId } : {}
160
+ } };
161
+ if (activeToolResultParts) activeToolResultParts.push(functionResponsePart);
162
+ else {
163
+ activeToolResultParts = [functionResponsePart];
164
+ contents.push({
165
+ role: "user",
166
+ parts: activeToolResultParts
167
+ });
168
+ }
169
+ if (hasImages && !modelSupportsMultimodalFunctionResponse) pendingToolResultImageTurns.push({
170
+ role: "user",
171
+ parts: [{ text: "Tool result image:" }, ...imageParts]
172
+ });
173
+ }
174
+ }
175
+ flushToolResultRun();
176
+ return contents;
177
+ }
178
+ const JSON_SCHEMA_META_DECLARATIONS = /* @__PURE__ */ new Set([
179
+ "$schema",
180
+ "$id",
181
+ "$anchor",
182
+ "$dynamicAnchor",
183
+ "$vocabulary",
184
+ "$comment",
185
+ "$defs",
186
+ "definitions"
187
+ ]);
188
+ /**
189
+ * Strip meta-declarations from a schema obj
190
+ */
191
+ function sanitizeForOpenApi(schema) {
192
+ if (typeof schema !== "object" || schema === null || Array.isArray(schema)) return schema;
193
+ const result = {};
194
+ for (const [key, value] of Object.entries(schema)) {
195
+ if (JSON_SCHEMA_META_DECLARATIONS.has(key)) continue;
196
+ result[key] = sanitizeForOpenApi(value);
197
+ }
198
+ return result;
199
+ }
200
+ /**
201
+ * Convert tools to Gemini function declarations format.
202
+ *
203
+ * By default uses `parametersJsonSchema` which supports full JSON Schema (including
204
+ * anyOf, oneOf, const, etc.). Set `useParameters` to true to use the legacy `parameters`
205
+ * field instead (OpenAPI 3.03 Schema). This is needed for Cloud Code Assist with Claude
206
+ * models, where the API translates `parameters` into Anthropic's `input_schema`.
207
+ */
208
+ function convertTools(tools, useParameters = false) {
209
+ if (tools.length === 0) return;
210
+ return [{ functionDeclarations: tools.map((tool) => ({
211
+ name: tool.name,
212
+ description: tool.description,
213
+ ...useParameters ? { parameters: sanitizeForOpenApi(tool.parameters) } : { parametersJsonSchema: tool.parameters }
214
+ })) }];
215
+ }
216
+ /**
217
+ * Map tool choice string to Gemini FunctionCallingConfigMode.
218
+ */
219
+ function mapToolChoice(choice) {
220
+ switch (choice) {
221
+ case "auto": return FunctionCallingConfigMode.AUTO;
222
+ case "none": return FunctionCallingConfigMode.NONE;
223
+ case "any": return FunctionCallingConfigMode.ANY;
224
+ default: return FunctionCallingConfigMode.AUTO;
225
+ }
226
+ }
227
+ function createGoogleAssistantOutput(model, api = model.api) {
228
+ return {
229
+ role: "assistant",
230
+ content: [],
231
+ api,
232
+ provider: model.provider,
233
+ model: model.id,
234
+ usage: {
235
+ input: 0,
236
+ output: 0,
237
+ cacheRead: 0,
238
+ cacheWrite: 0,
239
+ totalTokens: 0,
240
+ cost: {
241
+ input: 0,
242
+ output: 0,
243
+ cacheRead: 0,
244
+ cacheWrite: 0,
245
+ total: 0
246
+ }
247
+ },
248
+ stopReason: "stop",
249
+ timestamp: Date.now()
250
+ };
251
+ }
252
+ async function runGoogleGenerateContentLifecycle(params) {
253
+ const { stream, model, output, options } = params;
254
+ try {
255
+ const client = params.createClient();
256
+ let requestParams = params.buildParams();
257
+ const nextParams = await options?.onPayload?.(requestParams, model);
258
+ if (nextParams !== void 0) requestParams = nextParams;
259
+ await consumeGoogleGenerateContentStream({
260
+ chunks: await client.models.generateContentStream(requestParams),
261
+ model,
262
+ output,
263
+ stream,
264
+ signal: options?.signal,
265
+ nextToolCallId: params.nextToolCallId
266
+ });
267
+ } catch (error) {
268
+ for (const block of output.content) if ("index" in block) delete block.index;
269
+ output.stopReason = options?.signal?.aborted ? "aborted" : "error";
270
+ output.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
271
+ stream.push({
272
+ type: "error",
273
+ reason: output.stopReason,
274
+ error: output
275
+ });
276
+ stream.end();
277
+ }
278
+ }
279
+ function buildGoogleGenerateContentParams(model, context, options = {}, configHooks) {
280
+ const contents = convertMessages(model, context);
281
+ const generationConfig = {};
282
+ if (options.temperature !== void 0) generationConfig.temperature = options.temperature;
283
+ if (options.maxTokens !== void 0) generationConfig.maxOutputTokens = options.maxTokens;
284
+ if (options.stop !== void 0 && options.stop.length > 0) generationConfig.stopSequences = options.stop;
285
+ const config = {
286
+ ...Object.keys(generationConfig).length > 0 && generationConfig,
287
+ ...context.systemPrompt && { systemInstruction: sanitizeSurrogates(stripSystemPromptCacheBoundary(context.systemPrompt)) },
288
+ ...context.tools && context.tools.length > 0 && { tools: convertTools(context.tools) }
289
+ };
290
+ if (context.tools && context.tools.length > 0 && options.toolChoice) config.toolConfig = { functionCallingConfig: { mode: mapToolChoice(options.toolChoice) } };
291
+ else config.toolConfig = void 0;
292
+ if (options.thinking?.enabled && model.reasoning) {
293
+ const thinkingConfig = { includeThoughts: true };
294
+ if (options.thinking.level !== void 0) thinkingConfig.thinkingLevel = configHooks?.mapThinkingLevel ? configHooks.mapThinkingLevel(options.thinking.level) : options.thinking.level;
295
+ else if (options.thinking.budgetTokens !== void 0) thinkingConfig.thinkingBudget = options.thinking.budgetTokens;
296
+ config.thinkingConfig = thinkingConfig;
297
+ } else if (model.reasoning && options.thinking && !options.thinking.enabled) config.thinkingConfig = configHooks?.getDisabledThinkingConfig ? configHooks.getDisabledThinkingConfig(model) : getDisabledGoogleThinkingConfig(model);
298
+ if (options.signal) {
299
+ if (options.signal.aborted) throw new Error("Request aborted");
300
+ config.abortSignal = options.signal;
301
+ }
302
+ return {
303
+ model: model.id,
304
+ contents,
305
+ config
306
+ };
307
+ }
308
+ function buildGoogleSimpleThinking(model, options, config) {
309
+ if (!options?.reasoning || options.reasoning === "off") return { enabled: false };
310
+ const clampedReasoning = clampThinkingLevel(model, options.reasoning);
311
+ const effort = clampedReasoning === "off" || clampedReasoning === "max" ? "high" : clampedReasoning;
312
+ if (isGemini3ProModel(model) || isGemini3FlashModel(model) || config?.includeGemma4ThinkingLevel && isGemma4Model(model)) return {
313
+ enabled: true,
314
+ level: getGoogleThinkingLevel(effort, model, { includeGemma4: config?.includeGemma4ThinkingLevel })
315
+ };
316
+ return {
317
+ enabled: true,
318
+ budgetTokens: getGoogleBudget(model, effort, options.thinkingBudgets, { useFlashLiteBudgets: config?.useFlashLiteBudgets })
319
+ };
320
+ }
321
+ function getDisabledGoogleThinkingConfig(model, config) {
322
+ const mapThinkingLevel = (level) => config?.mapThinkingLevel ? config.mapThinkingLevel(level) : level;
323
+ if (isGemini3ProModel(model)) return { thinkingLevel: mapThinkingLevel("LOW") };
324
+ if (isGemini3FlashModel(model)) return { thinkingLevel: mapThinkingLevel("MINIMAL") };
325
+ if (config?.includeGemma4 && isGemma4Model(model)) return { thinkingLevel: mapThinkingLevel("MINIMAL") };
326
+ return { thinkingBudget: 0 };
327
+ }
328
+ function isGemma4Model(model) {
329
+ return /gemma-?4/.test(model.id.toLowerCase());
330
+ }
331
+ function isGemini3ProModel(model) {
332
+ return /gemini-3(?:\.\d+)?-pro/.test(model.id.toLowerCase());
333
+ }
334
+ function isGemini3FlashModel(model) {
335
+ return /gemini-3(?:\.\d+)?-flash/.test(model.id.toLowerCase());
336
+ }
337
+ function getGoogleThinkingLevel(effort, model, config) {
338
+ if (isGemini3ProModel(model)) switch (effort) {
339
+ case "minimal":
340
+ case "low": return "LOW";
341
+ case "medium":
342
+ case "high": return "HIGH";
343
+ }
344
+ if (config?.includeGemma4 && isGemma4Model(model)) switch (effort) {
345
+ case "minimal":
346
+ case "low": return "MINIMAL";
347
+ case "medium":
348
+ case "high": return "HIGH";
349
+ }
350
+ switch (effort) {
351
+ case "minimal": return "MINIMAL";
352
+ case "low": return "LOW";
353
+ case "medium": return "MEDIUM";
354
+ case "high": return "HIGH";
355
+ }
356
+ return "HIGH";
357
+ }
358
+ function getGoogleBudget(model, effort, customBudgets, config) {
359
+ if (customBudgets?.[effort] !== void 0) return customBudgets[effort];
360
+ if (model.id.includes("2.5-pro")) return {
361
+ minimal: 128,
362
+ low: 2048,
363
+ medium: 8192,
364
+ high: 32768
365
+ }[effort];
366
+ if (config?.useFlashLiteBudgets && model.id.includes("2.5-flash-lite")) return {
367
+ minimal: 512,
368
+ low: 2048,
369
+ medium: 8192,
370
+ high: 24576
371
+ }[effort];
372
+ if (model.id.includes("2.5-flash")) return {
373
+ minimal: 128,
374
+ low: 2048,
375
+ medium: 8192,
376
+ high: 24576
377
+ }[effort];
378
+ return -1;
379
+ }
380
+ /**
381
+ * Map Gemini FinishReason to our StopReason.
382
+ */
383
+ function mapStopReason(reason) {
384
+ switch (reason) {
385
+ case FinishReason.STOP: return "stop";
386
+ case FinishReason.MAX_TOKENS: return "length";
387
+ case FinishReason.BLOCKLIST:
388
+ case FinishReason.PROHIBITED_CONTENT:
389
+ case FinishReason.SPII:
390
+ case FinishReason.SAFETY:
391
+ case FinishReason.IMAGE_SAFETY:
392
+ case FinishReason.IMAGE_PROHIBITED_CONTENT:
393
+ case FinishReason.IMAGE_RECITATION:
394
+ case FinishReason.IMAGE_OTHER:
395
+ case FinishReason.RECITATION:
396
+ case FinishReason.FINISH_REASON_UNSPECIFIED:
397
+ case FinishReason.OTHER:
398
+ case FinishReason.LANGUAGE:
399
+ case FinishReason.MALFORMED_FUNCTION_CALL:
400
+ case FinishReason.UNEXPECTED_TOOL_CALL:
401
+ case FinishReason.NO_IMAGE: return "error";
402
+ default: throw new Error(`Unhandled stop reason: ${String(reason)}`);
403
+ }
404
+ }
405
+ async function consumeGoogleGenerateContentStream(params) {
406
+ params.stream.push({
407
+ type: "start",
408
+ partial: params.output
409
+ });
410
+ let currentBlock = null;
411
+ const blocks = params.output.content;
412
+ const toolCallIds = /* @__PURE__ */ new Set();
413
+ for (const block of blocks) if (block.type === "toolCall") toolCallIds.add(block.id);
414
+ const blockIndex = () => blocks.length - 1;
415
+ const endCurrentBlock = () => {
416
+ if (!currentBlock) return;
417
+ if (currentBlock.type === "text") params.stream.push({
418
+ type: "text_end",
419
+ contentIndex: blockIndex(),
420
+ content: currentBlock.text,
421
+ partial: params.output
422
+ });
423
+ else params.stream.push({
424
+ type: "thinking_end",
425
+ contentIndex: blockIndex(),
426
+ content: currentBlock.thinking,
427
+ partial: params.output
428
+ });
429
+ currentBlock = null;
430
+ };
431
+ for await (const chunk of params.chunks) {
432
+ params.output.responseId ||= chunk.responseId;
433
+ const candidate = chunk.candidates?.[0];
434
+ if (candidate?.content?.parts) for (const part of candidate.content.parts) {
435
+ if (part.text !== void 0) {
436
+ const isThinking = isThinkingPart(part);
437
+ if (!currentBlock || isThinking && currentBlock.type !== "thinking" || !isThinking && currentBlock.type !== "text") {
438
+ endCurrentBlock();
439
+ if (isThinking) {
440
+ currentBlock = {
441
+ type: "thinking",
442
+ thinking: "",
443
+ thinkingSignature: void 0
444
+ };
445
+ params.output.content.push(currentBlock);
446
+ params.stream.push({
447
+ type: "thinking_start",
448
+ contentIndex: blockIndex(),
449
+ partial: params.output
450
+ });
451
+ } else {
452
+ currentBlock = {
453
+ type: "text",
454
+ text: ""
455
+ };
456
+ params.output.content.push(currentBlock);
457
+ params.stream.push({
458
+ type: "text_start",
459
+ contentIndex: blockIndex(),
460
+ partial: params.output
461
+ });
462
+ }
463
+ }
464
+ if (currentBlock.type === "thinking") {
465
+ currentBlock.thinking += part.text;
466
+ currentBlock.thinkingSignature = retainThoughtSignature(currentBlock.thinkingSignature, part.thoughtSignature);
467
+ params.stream.push({
468
+ type: "thinking_delta",
469
+ contentIndex: blockIndex(),
470
+ delta: part.text,
471
+ partial: params.output
472
+ });
473
+ } else {
474
+ currentBlock.text += part.text;
475
+ currentBlock.textSignature = retainThoughtSignature(currentBlock.textSignature, part.thoughtSignature);
476
+ params.stream.push({
477
+ type: "text_delta",
478
+ contentIndex: blockIndex(),
479
+ delta: part.text,
480
+ partial: params.output
481
+ });
482
+ }
483
+ }
484
+ if (part.functionCall) {
485
+ endCurrentBlock();
486
+ const providedId = part.functionCall.id;
487
+ const toolCall = {
488
+ type: "toolCall",
489
+ id: !providedId || toolCallIds.has(providedId) ? params.nextToolCallId(part.functionCall.name) : providedId,
490
+ name: part.functionCall.name || "",
491
+ arguments: part.functionCall.args ?? {},
492
+ ...part.thoughtSignature && { thoughtSignature: part.thoughtSignature }
493
+ };
494
+ params.output.content.push(toolCall);
495
+ toolCallIds.add(toolCall.id);
496
+ params.stream.push({
497
+ type: "toolcall_start",
498
+ contentIndex: blockIndex(),
499
+ partial: params.output
500
+ });
501
+ params.stream.push({
502
+ type: "toolcall_delta",
503
+ contentIndex: blockIndex(),
504
+ delta: JSON.stringify(toolCall.arguments),
505
+ partial: params.output
506
+ });
507
+ params.stream.push({
508
+ type: "toolcall_end",
509
+ contentIndex: blockIndex(),
510
+ toolCall,
511
+ partial: params.output
512
+ });
513
+ }
514
+ }
515
+ if (candidate?.finishReason) {
516
+ params.output.stopReason = mapStopReason(candidate.finishReason);
517
+ if (params.output.stopReason === "stop" && params.output.content.some((block) => block.type === "toolCall")) params.output.stopReason = "toolUse";
518
+ }
519
+ if (chunk.usageMetadata) {
520
+ params.output.usage = {
521
+ input: (chunk.usageMetadata.promptTokenCount || 0) - (chunk.usageMetadata.cachedContentTokenCount || 0),
522
+ output: (chunk.usageMetadata.candidatesTokenCount || 0) + (chunk.usageMetadata.thoughtsTokenCount || 0),
523
+ cacheRead: chunk.usageMetadata.cachedContentTokenCount || 0,
524
+ cacheWrite: 0,
525
+ totalTokens: chunk.usageMetadata.totalTokenCount || 0,
526
+ cost: {
527
+ input: 0,
528
+ output: 0,
529
+ cacheRead: 0,
530
+ cacheWrite: 0,
531
+ total: 0
532
+ }
533
+ };
534
+ calculateCost(params.model, params.output.usage);
535
+ }
536
+ }
537
+ endCurrentBlock();
538
+ if (params.signal?.aborted) throw new Error("Request was aborted");
539
+ if (params.output.stopReason === "aborted" || params.output.stopReason === "error") throw new Error("An unknown error occurred");
540
+ params.stream.push({
541
+ type: "done",
542
+ reason: params.output.stopReason,
543
+ message: params.output
544
+ });
545
+ params.stream.end();
546
+ }
547
+ //#endregion
548
+ export { runGoogleGenerateContentLifecycle as a, getDisabledGoogleThinkingConfig as i, buildGoogleSimpleThinking as n, createGoogleAssistantOutput as r, buildGoogleGenerateContentParams as t };
@@ -0,0 +1,111 @@
1
+ import { t as AssistantMessageEventStream } from "./event-stream-ReMmOTzX.mjs";
2
+ import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-4t713IeR.mjs";
3
+ import { o as buildBaseOptions } from "./transform-messages-BhGF_fF4.mjs";
4
+ import { a as runGoogleGenerateContentLifecycle, i as getDisabledGoogleThinkingConfig, n as buildGoogleSimpleThinking, r as createGoogleAssistantOutput, t as buildGoogleGenerateContentParams } from "./google-shared-ZPSl2qTi.mjs";
5
+ import { GoogleGenAI, ResourceScope, ThinkingLevel } from "@google/genai";
6
+ //#region packages/ai/src/providers/google-vertex.ts
7
+ const API_VERSION = "v1";
8
+ const GCP_VERTEX_CREDENTIALS_MARKER = "gcp-vertex-credentials";
9
+ const THINKING_LEVEL_MAP = {
10
+ THINKING_LEVEL_UNSPECIFIED: ThinkingLevel.THINKING_LEVEL_UNSPECIFIED,
11
+ MINIMAL: ThinkingLevel.MINIMAL,
12
+ LOW: ThinkingLevel.LOW,
13
+ MEDIUM: ThinkingLevel.MEDIUM,
14
+ HIGH: ThinkingLevel.HIGH
15
+ };
16
+ let toolCallCounter = 0;
17
+ const streamGoogleVertex = (model, context, options) => {
18
+ const stream = new AssistantMessageEventStream();
19
+ runGoogleGenerateContentLifecycle({
20
+ stream,
21
+ model,
22
+ output: createGoogleAssistantOutput(model, "google-vertex"),
23
+ options,
24
+ createClient: () => {
25
+ const apiKey = resolveApiKey(options);
26
+ return apiKey ? createClientWithApiKey(model, apiKey, options?.headers) : createClient(model, resolveProject(options), resolveLocation(options), options?.headers);
27
+ },
28
+ buildParams: () => buildParams(model, context, options),
29
+ nextToolCallId: (name) => `${name}_${Date.now()}_${++toolCallCounter}`
30
+ });
31
+ return stream;
32
+ };
33
+ const streamSimpleGoogleVertex = (model, context, options) => {
34
+ const base = buildBaseOptions(model, options, void 0);
35
+ return streamGoogleVertex(model, context, {
36
+ ...base,
37
+ thinking: buildGoogleSimpleThinking(model, options)
38
+ });
39
+ };
40
+ function createClient(model, project, location, optionsHeaders) {
41
+ return new GoogleGenAI({
42
+ vertexai: true,
43
+ project,
44
+ location,
45
+ apiVersion: API_VERSION,
46
+ httpOptions: buildHttpOptions(model, optionsHeaders)
47
+ });
48
+ }
49
+ function createClientWithApiKey(model, apiKey, optionsHeaders) {
50
+ return new GoogleGenAI({
51
+ vertexai: true,
52
+ apiKey: getAiTransportHost().resolveSecretSentinel(apiKey),
53
+ apiVersion: API_VERSION,
54
+ httpOptions: buildHttpOptions(model, optionsHeaders)
55
+ });
56
+ }
57
+ function buildHttpOptions(model, optionsHeaders) {
58
+ const httpOptions = {};
59
+ const baseUrl = resolveCustomBaseUrl(model.baseUrl);
60
+ if (baseUrl) {
61
+ httpOptions.baseUrl = baseUrl;
62
+ httpOptions.baseUrlResourceScope = ResourceScope.COLLECTION;
63
+ if (baseUrlIncludesApiVersion(baseUrl)) httpOptions.apiVersion = "";
64
+ }
65
+ if (model.headers || optionsHeaders) httpOptions.headers = resolveAiTransportHeaderSentinels({
66
+ ...model.headers,
67
+ ...optionsHeaders
68
+ });
69
+ return Object.keys(httpOptions).length > 0 ? httpOptions : void 0;
70
+ }
71
+ function resolveCustomBaseUrl(baseUrl) {
72
+ const trimmed = baseUrl.trim();
73
+ if (!trimmed || trimmed.includes("{location}")) return;
74
+ return trimmed;
75
+ }
76
+ function baseUrlIncludesApiVersion(baseUrl) {
77
+ try {
78
+ return new URL(baseUrl).pathname.split("/").some((part) => /^v\d+(?:beta\d*)?$/.test(part));
79
+ } catch {
80
+ return /(?:^|\/)v\d+(?:beta\d*)?(?:\/|$)/.test(baseUrl);
81
+ }
82
+ }
83
+ function resolveApiKey(options) {
84
+ const apiKey = options?.apiKey?.trim() || process.env.GOOGLE_CLOUD_API_KEY?.trim();
85
+ if (!apiKey || apiKey === GCP_VERTEX_CREDENTIALS_MARKER || isPlaceholderApiKey(apiKey)) return;
86
+ return apiKey;
87
+ }
88
+ function isPlaceholderApiKey(apiKey) {
89
+ return /^<[^>]+>$/.test(apiKey);
90
+ }
91
+ function resolveProject(options) {
92
+ const project = options?.project || process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT;
93
+ if (!project) throw new Error("Vertex AI requires a project ID. Set GOOGLE_CLOUD_PROJECT/GCLOUD_PROJECT or pass project in options.");
94
+ return project;
95
+ }
96
+ function resolveLocation(options) {
97
+ const location = options?.location || process.env.GOOGLE_CLOUD_LOCATION;
98
+ if (!location) throw new Error("Vertex AI requires a location. Set GOOGLE_CLOUD_LOCATION or pass location in options.");
99
+ return location;
100
+ }
101
+ function buildParams(model, context, options = {}) {
102
+ return buildGoogleGenerateContentParams(model, context, options, {
103
+ mapThinkingLevel: mapVertexThinkingLevel,
104
+ getDisabledThinkingConfig: (modelLocal) => getDisabledGoogleThinkingConfig(modelLocal, { mapThinkingLevel: mapVertexThinkingLevel })
105
+ });
106
+ }
107
+ function mapVertexThinkingLevel(level) {
108
+ return THINKING_LEVEL_MAP[level];
109
+ }
110
+ //#endregion
111
+ export { streamGoogleVertex, streamSimpleGoogleVertex };
@@ -0,0 +1,16 @@
1
+ //#region packages/ai/src/utils/hash.ts
2
+ /** Fast deterministic hash to shorten long strings */
3
+ function shortHash(str) {
4
+ let h1 = 3735928559;
5
+ let h2 = 1103547991;
6
+ for (let i = 0; i < str.length; i++) {
7
+ const ch = str.charCodeAt(i);
8
+ h1 = Math.imul(h1 ^ ch, 2654435761);
9
+ h2 = Math.imul(h2 ^ ch, 1597334677);
10
+ }
11
+ h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
12
+ h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
13
+ return (h2 >>> 0).toString(36) + (h1 >>> 0).toString(36);
14
+ }
15
+ //#endregion
16
+ export { shortHash as t };
@@ -0,0 +1,9 @@
1
+ //#region packages/ai/src/utils/headers.ts
2
+ /** Converts a Headers object to a plain record for provider request handling. */
3
+ function headersToRecord(headers) {
4
+ const result = {};
5
+ for (const [key, value] of headers.entries()) result[key] = value;
6
+ return result;
7
+ }
8
+ //#endregion
9
+ export { headersToRecord as t };