@anvia/gemini 0.4.1 → 1.0.0-rc.10

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/index.js CHANGED
@@ -10,15 +10,13 @@ __export(gemini_exports, {
10
10
  GEMINI_2_5_FLASH_IMAGE: () => GEMINI_2_5_FLASH_IMAGE,
11
11
  GEMINI_3_PRO_IMAGE_PREVIEW: () => GEMINI_3_PRO_IMAGE_PREVIEW,
12
12
  GeminiClient: () => GeminiClient,
13
- GeminiCompletionModel: () => GeminiCompletionModel,
14
- GeminiEmbeddingModel: () => GeminiEmbeddingModel,
15
- GeminiImageGenerationModel: () => GeminiImageGenerationModel,
16
- GeminiImagenGenerationModel: () => GeminiImagenGenerationModel,
17
- GeminiTranscriptionModel: () => GeminiTranscriptionModel,
18
13
  IMAGEN_4_GENERATE: () => IMAGEN_4_GENERATE
19
14
  });
20
15
 
21
16
  // src/gemini/client.ts
17
+ import {
18
+ resolveModelContextLimits
19
+ } from "@anvia/core/completion";
22
20
  import {
23
21
  ModelListingError
24
22
  } from "@anvia/core/model-listing";
@@ -26,9 +24,9 @@ import { GoogleGenAI } from "@google/genai";
26
24
 
27
25
  // src/gemini/completion.ts
28
26
  import {
29
- AssistantContent,
30
27
  assertCompletionRequestSupported,
31
- resolveCompletionModelInfo,
28
+ CompletionProviderOutputError,
29
+ isJsonValue,
32
30
  Usage,
33
31
  withContextUsage
34
32
  } from "@anvia/core/completion";
@@ -48,82 +46,35 @@ function orderedRequestMessages(request) {
48
46
  return messages;
49
47
  }
50
48
 
51
- // src/gemini/models.ts
52
- var CONTEXT_1M_64K = {
53
- contextWindow: 1048576,
54
- maxInputTokens: 1048576,
55
- maxOutputTokens: 65536
56
- };
57
- var GEMINI_COMPLETION_MODEL_CONTEXT_LIMITS = {
58
- "gemini-2.0-flash": {
59
- contextWindow: 1048576,
60
- maxInputTokens: 1048576,
61
- maxOutputTokens: 8192
62
- },
63
- "gemini-2.0-flash-lite": {
64
- contextWindow: 1048576,
65
- maxInputTokens: 1048576,
66
- maxOutputTokens: 8192
67
- },
68
- "gemini-2.5-flash": CONTEXT_1M_64K,
69
- "gemini-2.5-flash-image": {
70
- contextWindow: 32768,
71
- maxInputTokens: 32768,
72
- maxOutputTokens: 32768
73
- },
74
- "gemini-2.5-flash-lite": CONTEXT_1M_64K,
75
- "gemini-2.5-flash-preview-tts": {
76
- contextWindow: 8192,
77
- maxInputTokens: 8192,
78
- maxOutputTokens: 16384
79
- },
80
- "gemini-2.5-pro": CONTEXT_1M_64K,
81
- "gemini-2.5-pro-preview-tts": {
82
- contextWindow: 8192,
83
- maxInputTokens: 8192,
84
- maxOutputTokens: 16384
85
- },
86
- "gemini-3-flash-preview": CONTEXT_1M_64K,
87
- "gemini-3-pro-image-preview": {
88
- contextWindow: 131072,
89
- maxInputTokens: 131072,
90
- maxOutputTokens: 32768
91
- },
92
- "gemini-3-pro-preview": CONTEXT_1M_64K,
93
- "gemini-3.1-flash-image-preview": {
94
- contextWindow: 65536,
95
- maxInputTokens: 65536,
96
- maxOutputTokens: 65536
97
- },
98
- "gemini-3.1-flash-lite": CONTEXT_1M_64K,
99
- "gemini-3.1-flash-lite-preview": CONTEXT_1M_64K,
100
- "gemini-3.1-pro-preview": CONTEXT_1M_64K,
101
- "gemini-3.1-pro-preview-customtools": CONTEXT_1M_64K,
102
- "gemini-3.5-flash": CONTEXT_1M_64K,
103
- "gemini-flash-latest": CONTEXT_1M_64K,
104
- "gemini-flash-lite-latest": CONTEXT_1M_64K,
105
- "gemma-4-26b-a4b-it": {
106
- contextWindow: 262144,
107
- maxInputTokens: 262144,
108
- maxOutputTokens: 32768
109
- },
110
- "gemma-4-31b-it": {
111
- contextWindow: 262144,
112
- maxInputTokens: 262144,
113
- maxOutputTokens: 32768
114
- }
115
- };
49
+ // src/gemini/retry.ts
50
+ function disableGeminiNativeRetries(config) {
51
+ const httpOptions = isPlainObject(config.httpOptions) ? config.httpOptions : {};
52
+ const retryOptions = isPlainObject(httpOptions.retryOptions) ? httpOptions.retryOptions : {};
53
+ return {
54
+ ...config,
55
+ httpOptions: {
56
+ ...httpOptions,
57
+ retryOptions: {
58
+ ...retryOptions,
59
+ attempts: 1
60
+ }
61
+ }
62
+ };
63
+ }
64
+ function isPlainObject(value) {
65
+ return typeof value === "object" && value !== null && !Array.isArray(value);
66
+ }
116
67
 
117
68
  // src/gemini/completion.ts
118
69
  var GeminiCompletionModel = class {
119
- constructor(client, defaultModel = "gemini-2.5-flash", metadataOptions = {}) {
70
+ constructor(client, modelId, contextLimits) {
120
71
  this.client = client;
121
- this.defaultModel = defaultModel;
122
- this.metadataOptions = metadataOptions;
72
+ this.modelId = modelId;
73
+ this.contextLimits = contextLimits;
123
74
  }
124
75
  client;
125
- defaultModel;
126
- metadataOptions;
76
+ modelId;
77
+ contextLimits;
127
78
  provider = "gemini";
128
79
  capabilities = {
129
80
  streaming: true,
@@ -134,62 +85,76 @@ var GeminiCompletionModel = class {
134
85
  outputSchema: true,
135
86
  reasoning: true
136
87
  };
137
- getModelInfo(model = this.defaultModel) {
138
- return resolveCompletionModelInfo(
139
- model,
140
- GEMINI_COMPLETION_MODEL_CONTEXT_LIMITS,
141
- this.metadataOptions.modelOverrides
142
- );
88
+ modelInfo() {
89
+ return this.contextLimits === void 0 ? void 0 : { modelId: this.modelId, context: this.contextLimits };
143
90
  }
144
91
  traceRequest(request, options = {}) {
145
- const params = toGeminiGenerateContentParams(this.defaultModel, request);
92
+ const params = toGeminiGenerateContentParams(this.modelId, request);
146
93
  return providerRequestSummary(params, request, options);
147
94
  }
148
- async completion(request) {
95
+ async completion(request, options) {
149
96
  assertCompletionRequestSupported(this, request);
150
- const params = toGeminiGenerateContentParams(this.defaultModel, request);
97
+ const params = toGeminiGenerateContentParams(this.modelId, request);
98
+ applyAbortSignal(params, options);
151
99
  const response = await this.client.models.generateContent(params);
152
- return withContextUsage(
153
- fromGeminiGenerateContentResponse(response),
154
- this.getModelInfo(request.model ?? this.defaultModel)
155
- );
100
+ return withContextUsage(fromGeminiGenerateContentResponse(response), this.modelInfo());
156
101
  }
157
- async *streamCompletion(request) {
102
+ async *streamCompletion(request, options) {
158
103
  assertCompletionRequestSupported(this, request, { streaming: true });
159
- const params = toGeminiGenerateContentParams(this.defaultModel, request);
104
+ const params = toGeminiGenerateContentParams(this.modelId, request);
105
+ applyAbortSignal(params, options);
160
106
  const stream = await this.client.models.generateContentStream(params);
107
+ const streamState = new GeminiCompletionStreamState();
161
108
  for await (const chunk of stream) {
162
- for (const event of fromGeminiGenerateContentStreamChunk(chunk)) {
163
- yield event.type === "final" ? {
164
- ...event,
165
- response: withContextUsage(
166
- event.response,
167
- this.getModelInfo(request.model ?? this.defaultModel)
168
- )
169
- } : event;
109
+ const mapping = mapGeminiGenerateContentStreamChunk(chunk);
110
+ streamState.accept(chunk, mapping);
111
+ for (const event of mapping.events) {
112
+ if (event.type !== "final") {
113
+ yield event;
114
+ }
170
115
  }
171
116
  }
117
+ streamState.assertComplete();
118
+ const finalEvent = streamState.finalEvent();
119
+ if (finalEvent !== void 0) {
120
+ yield {
121
+ ...finalEvent,
122
+ response: withContextUsage(finalEvent.response, this.modelInfo())
123
+ };
124
+ }
172
125
  }
173
126
  };
174
- function toGeminiGenerateContentParams(defaultModel, request) {
127
+ function toGeminiGenerateContentParams(modelId, request) {
175
128
  const messages = requestMessages(request);
176
- const config = geminiConfig(request, messages);
129
+ if (request.providerOptions !== void 0 && (!isPlainObject2(request.providerOptions) || !isJsonValue(request.providerOptions))) {
130
+ throw new TypeError("Gemini providerOptions must be a JSON object.");
131
+ }
132
+ const providerOptions = request.providerOptions ?? {};
133
+ const { config: providerConfigValue, ...providerTopLevel } = providerOptions;
134
+ if (providerConfigValue !== void 0 && !isPlainObject2(providerConfigValue)) {
135
+ throw new TypeError("Gemini providerOptions.config must be a JSON object.");
136
+ }
137
+ const providerConfig = providerConfigValue === void 0 ? {} : { ...providerConfigValue };
138
+ delete providerConfig.tools;
139
+ const config = disableGeminiNativeRetries({
140
+ ...providerConfig,
141
+ ...geminiConfig(request, messages)
142
+ });
177
143
  const params = {
178
- model: request.model ?? defaultModel,
144
+ ...providerTopLevel,
145
+ model: modelId,
179
146
  contents: messagesToGeminiContents(messages),
180
147
  config
181
148
  };
182
- if (request.additionalParams !== void 0 && isPlainObject(request.additionalParams)) {
183
- const { config: additionalConfig, ...additionalTopLevel } = request.additionalParams;
184
- Object.assign(params, additionalTopLevel);
185
- if (isPlainObject(additionalConfig)) {
186
- params.config = { ...config, ...additionalConfig };
187
- }
188
- }
189
149
  return params;
190
150
  }
151
+ function applyAbortSignal(params, options) {
152
+ if (options?.abortSignal === void 0) return;
153
+ const config = isPlainObject2(params.config) ? params.config : {};
154
+ params.config = { ...config, abortSignal: options.abortSignal };
155
+ }
191
156
  function providerRequestSummary(params, request, options) {
192
- const config = isPlainObject(params.config) ? params.config : {};
157
+ const config = isPlainObject2(params.config) ? params.config : {};
193
158
  return compactJsonObject({
194
159
  provider: "gemini",
195
160
  api: options.stream === true ? "models.generateContentStream" : "models.generateContent",
@@ -205,7 +170,7 @@ function providerRequestSummary(params, request, options) {
205
170
  temperature: request.temperature,
206
171
  maxTokens: request.maxTokens,
207
172
  toolChoice: toolChoiceSummary(request.toolChoice),
208
- additionalParamKeys: isPlainObject(request.additionalParams) ? Object.keys(request.additionalParams).sort() : void 0
173
+ providerOptionKeys: isPlainObject2(request.providerOptions) ? Object.keys(request.providerOptions).sort() : void 0
209
174
  });
210
175
  }
211
176
  function toolChoiceSummary(toolChoice) {
@@ -217,10 +182,10 @@ function toolChoiceSummary(toolChoice) {
217
182
  function compactJsonObject(values) {
218
183
  return Object.fromEntries(
219
184
  Object.entries(values).flatMap(([key, value]) => {
220
- if (value === void 0) {
185
+ if (!isJsonValue(value)) {
221
186
  return [];
222
187
  }
223
- return [[key, toJsonValue(value)]];
188
+ return [[key, value]];
224
189
  })
225
190
  );
226
191
  }
@@ -269,11 +234,11 @@ function messagesToGeminiContents(messages) {
269
234
  }
270
235
  if (message.role === "assistant") {
271
236
  const content2 = assistantMessageToGeminiContent(message);
272
- for (const item of message.content) {
273
- if (item.type === "tool_call") {
274
- toolNamesById.set(item.id, item.function.name);
237
+ for (const item of typeof message.content === "string" ? [] : message.content) {
238
+ if (item.type === "tool-call") {
239
+ toolNamesById.set(item.toolCallId, item.toolName);
275
240
  if (item.callId !== void 0) {
276
- toolNamesById.set(item.callId, item.function.name);
241
+ toolNamesById.set(item.callId, item.toolName);
277
242
  }
278
243
  }
279
244
  }
@@ -292,19 +257,26 @@ function messagesToGeminiContents(messages) {
292
257
  function userMessageToGeminiContent(message) {
293
258
  return {
294
259
  role: "user",
295
- parts: message.content.map(userContentToGeminiPart)
260
+ parts: typeof message.content === "string" ? [{ text: message.content }] : message.content.map(userContentToGeminiPart)
296
261
  };
297
262
  }
298
263
  function toolMessageToGeminiContent(message, toolNamesById) {
299
264
  return {
300
265
  role: "user",
301
- parts: message.content.map((content) => toolContentToGeminiPart(content, toolNamesById))
266
+ parts: message.content.map((content) => {
267
+ if (content.type !== "tool-result") {
268
+ throw new TypeError(
269
+ "Anvia interaction responses must be resolved by Agent before provider calls."
270
+ );
271
+ }
272
+ return toolContentToGeminiPart(content, toolNamesById);
273
+ })
302
274
  };
303
275
  }
304
276
  function assistantMessageToGeminiContent(message) {
305
277
  return {
306
278
  role: "model",
307
- parts: message.content.flatMap((content) => {
279
+ parts: typeof message.content === "string" ? [{ text: message.content }] : message.content.flatMap((content) => {
308
280
  if (content.type === "text") {
309
281
  const part = { text: content.text };
310
282
  if (content.signature !== void 0) {
@@ -312,10 +284,10 @@ function assistantMessageToGeminiContent(message) {
312
284
  }
313
285
  return [part];
314
286
  }
315
- if (content.type === "tool_call") {
287
+ if (content.type === "tool-call") {
316
288
  const functionCall = {
317
- name: content.function.name,
318
- args: content.function.arguments ?? {}
289
+ name: content.toolName,
290
+ args: content.input
319
291
  };
320
292
  if (content.callId !== void 0) {
321
293
  functionCall.id = content.callId;
@@ -326,8 +298,8 @@ function assistantMessageToGeminiContent(message) {
326
298
  }
327
299
  return [part];
328
300
  }
329
- if (content.type === "reasoning" && content.content !== void 0) {
330
- return content.content.flatMap((reasoning) => {
301
+ if (content.type === "reasoning" && content.details !== void 0) {
302
+ return content.details.flatMap((reasoning) => {
331
303
  if (reasoning.type !== "text" && reasoning.type !== "summary") {
332
304
  return [];
333
305
  }
@@ -338,8 +310,10 @@ function assistantMessageToGeminiContent(message) {
338
310
  return [part];
339
311
  });
340
312
  }
341
- if (content.type === "image") {
342
- throw new Error("Gemini does not support image content in assistant history yet");
313
+ if (content.type === "image" || content.type === "file") {
314
+ throw new Error(
315
+ "Gemini does not support image or file content in assistant history yet"
316
+ );
343
317
  }
344
318
  return [];
345
319
  })
@@ -355,18 +329,18 @@ function userContentToGeminiPart(content) {
355
329
  return documentContentToGeminiPart(content);
356
330
  }
357
331
  function imageContentToGeminiPart(content) {
358
- if (content.source.type === "base64") {
332
+ if (content.image.type === "data") {
359
333
  return {
360
334
  inlineData: {
361
- mimeType: content.source.mediaType,
362
- data: content.source.data
335
+ mimeType: content.mediaType ?? "image/png",
336
+ data: content.image.data
363
337
  }
364
338
  };
365
339
  }
366
340
  return {
367
341
  fileData: {
368
- fileUri: content.source.url,
369
- mimeType: mimeTypeFromImageUrl(content.source.url)
342
+ fileUri: content.image.url,
343
+ mimeType: content.mediaType ?? mimeTypeFromImageUrl(content.image.url)
370
344
  }
371
345
  };
372
346
  }
@@ -388,29 +362,29 @@ function safeUrlPathname(url) {
388
362
  }
389
363
  }
390
364
  function documentContentToGeminiPart(content) {
391
- if (content.source.type === "text") {
392
- return { text: content.source.text };
365
+ if (content.data.type === "text") {
366
+ return { text: content.data.text };
393
367
  }
394
- if (content.source.type === "base64") {
368
+ if (content.data.type === "data") {
395
369
  return {
396
370
  inlineData: {
397
- mimeType: content.source.mediaType,
398
- data: content.source.data
371
+ mimeType: content.mediaType,
372
+ data: content.data.data
399
373
  }
400
374
  };
401
375
  }
402
376
  return {
403
377
  fileData: {
404
- fileUri: content.source.url,
405
- mimeType: content.source.mediaType
378
+ fileUri: content.data.url,
379
+ mimeType: content.mediaType
406
380
  }
407
381
  };
408
382
  }
409
383
  function toolContentToGeminiPart(content, toolNamesById) {
410
- const id = content.callId ?? content.id;
384
+ const id = content.callId ?? content.toolCallId;
411
385
  const functionResponse = {
412
- name: content.toolName ?? toolNamesById.get(id) ?? content.id,
413
- response: toolResultResponse(content.content)
386
+ name: content.toolName || toolNamesById.get(id) || content.toolCallId,
387
+ response: toolResultResponse(content)
414
388
  };
415
389
  if (content.callId !== void 0) {
416
390
  functionResponse.id = content.callId;
@@ -418,10 +392,21 @@ function toolContentToGeminiPart(content, toolNamesById) {
418
392
  return { functionResponse };
419
393
  }
420
394
  function toolResultResponse(content) {
395
+ const output = content.output;
396
+ if (output.type === "json") {
397
+ return { result: output.value };
398
+ }
399
+ if (output.type === "text") {
400
+ return { content: output.value };
401
+ }
402
+ if (output.type === "error-json" || output.type === "error-text") {
403
+ return { error: output.value };
404
+ }
405
+ if (output.type === "execution-denied") {
406
+ return { error: output.reason ?? "Tool execution was denied." };
407
+ }
421
408
  return {
422
- content: content.map(
423
- (item) => item.type === "text" ? item.text : `[image:${item.mediaType ?? "image/png"}]`
424
- ).join("\n")
409
+ content: output.value.map((item) => item.type === "text" ? item.text : `[file:${item.mediaType}]`).join("\n")
425
410
  };
426
411
  }
427
412
  function toolDefinitionToGemini(tool) {
@@ -449,29 +434,73 @@ function toolChoiceToGemini(toolChoice) {
449
434
  };
450
435
  }
451
436
  function fromGeminiGenerateContentResponse(response) {
452
- const raw = response;
453
- const choice = assistantContentFromGeminiResponse(raw);
437
+ const raw = isPlainObject2(response) ? response : {};
438
+ const usage = usageFromGemini(raw.usageMetadata);
439
+ const parts = candidateParts(raw, usage);
440
+ const providerFinishReason = providerFinishReasonFromGeminiResponse(raw);
441
+ const finishError = geminiToolFinishError(
442
+ providerFinishReason,
443
+ hasGeminiFunctionCallMarker(raw, parts),
444
+ usage
445
+ );
446
+ if (finishError !== void 0) throw finishError;
447
+ const choice = assistantContentFromGeminiResponse(raw, usage);
454
448
  const result = {
455
449
  choice,
456
- usage: usageFromGemini(raw.usageMetadata),
450
+ usage,
457
451
  rawResponse: response
458
452
  };
453
+ applyGeminiFinishReason(result, raw);
459
454
  const id = stringFrom(raw.responseId) ?? stringFrom(raw.id);
460
455
  if (id !== void 0) {
461
456
  result.messageId = id;
462
457
  }
458
+ assertSafeGeminiCompletionResponse(result);
463
459
  return result;
464
460
  }
465
- function fromGeminiGenerateContentStreamChunk(chunk) {
466
- if (!isPlainObject(chunk)) {
467
- return [];
461
+ function applyGeminiFinishReason(response, raw, hasStreamedToolCalls = false) {
462
+ const value = providerFinishReasonFromGeminiResponse(raw);
463
+ if (value === void 0) return;
464
+ applyGeminiFinishReasonValue(response, value, hasStreamedToolCalls);
465
+ }
466
+ function applyGeminiFinishReasonValue(response, value, hasStreamedToolCalls) {
467
+ response.finishReason = geminiFinishReason(
468
+ value,
469
+ hasStreamedToolCalls || response.choice.some((part) => part.type === "tool-call")
470
+ );
471
+ response.providerFinishReason = value;
472
+ }
473
+ function geminiFinishReason(value, hasToolCalls) {
474
+ if (value === "MAX_TOKENS") return "length";
475
+ if (value === "SAFETY" || value === "RECITATION" || value === "BLOCKLIST" || value === "PROHIBITED_CONTENT" || value === "SPII" || value === "IMAGE_SAFETY" || value === "IMAGE_PROHIBITED_CONTENT") {
476
+ return "content-filter";
477
+ }
478
+ if (value === "STOP") {
479
+ return hasToolCalls ? "tool-calls" : "stop";
480
+ }
481
+ return "other";
482
+ }
483
+ function mapGeminiGenerateContentStreamChunk(chunk) {
484
+ if (!isPlainObject2(chunk)) {
485
+ return {
486
+ events: [],
487
+ toolCalls: [],
488
+ hasToolCallMarker: false,
489
+ hasSyntheticToolCalls: false
490
+ };
468
491
  }
469
492
  const events = [];
470
- const directText = typeof chunk.text === "string" ? chunk.text : "";
471
- if (directText.length > 0 && candidateParts(chunk).length === 0) {
493
+ const usage = usageFromGemini(chunk.usageMetadata);
494
+ const parts = candidateParts(chunk, usage);
495
+ const providerFinishReason = providerFinishReasonFromGeminiResponse(chunk);
496
+ const hasToolCallMarker = hasGeminiFunctionCallMarker(chunk, parts);
497
+ const terminalError = providerFinishReason === void 0 ? void 0 : geminiToolFinishError(providerFinishReason, hasToolCallMarker, usage);
498
+ const calls = terminalError === void 0 ? functionCallsFromGeminiResponse(chunk, parts, usage) : [];
499
+ const directText = textFromGeminiResponse(chunk, parts);
500
+ if (terminalError === void 0 && directText.length > 0 && parts.length === 0) {
472
501
  events.push({ type: "text_delta", delta: directText });
473
502
  }
474
- for (const part of candidateParts(chunk)) {
503
+ for (const { part } of terminalError === void 0 ? parts : []) {
475
504
  if (typeof part.text === "string" && part.text.length > 0) {
476
505
  if (part.thought === true) {
477
506
  events.push({ type: "reasoning_delta", delta: part.text, contentType: "summary" });
@@ -480,18 +509,22 @@ function fromGeminiGenerateContentStreamChunk(chunk) {
480
509
  }
481
510
  }
482
511
  }
483
- for (const call of functionCallsFromGeminiResponse(chunk)) {
512
+ for (const call of calls) {
484
513
  events.push(
485
- toolCallDelta(call.id ?? call.name, {
486
- callId: call.id,
514
+ toolCallDelta(call.toolCallId, {
515
+ callId: call.callId,
487
516
  name: call.name,
488
517
  signature: call.signature
489
518
  })
490
519
  );
520
+ const argumentsDelta = JSON.stringify(call.args);
521
+ if (argumentsDelta === void 0) {
522
+ throw invalidGeminiToolCallArguments(call.toolCallId, usage);
523
+ }
491
524
  events.push(
492
- toolCallDelta(call.id ?? call.name, {
493
- callId: call.id,
494
- argumentsDelta: JSON.stringify(call.args ?? {}),
525
+ toolCallDelta(call.toolCallId, {
526
+ callId: call.callId,
527
+ argumentsDelta,
495
528
  argumentsMode: "replace"
496
529
  })
497
530
  );
@@ -500,113 +533,522 @@ function fromGeminiGenerateContentStreamChunk(chunk) {
500
533
  if (id !== void 0) {
501
534
  events.push({ type: "message_id", id });
502
535
  }
503
- if (isPlainObject(chunk.usageMetadata)) {
504
- events.push({ type: "final", response: fromGeminiGenerateContentResponse(chunk) });
536
+ if (isPlainObject2(chunk.usageMetadata)) {
537
+ if (terminalError === void 0) {
538
+ events.push({ type: "final", response: fromGeminiGenerateContentResponse(chunk) });
539
+ } else {
540
+ const response = { choice: [], usage, rawResponse: chunk };
541
+ if (providerFinishReason !== void 0) {
542
+ applyGeminiFinishReasonValue(response, providerFinishReason, true);
543
+ }
544
+ events.push({ type: "final", response });
545
+ }
505
546
  }
506
- return events;
547
+ return providerFinishReason === void 0 ? {
548
+ events,
549
+ toolCalls: calls.map(toolCallFromGeminiFunctionCall),
550
+ hasToolCallMarker,
551
+ hasSyntheticToolCalls: calls.some((call) => call.callId === void 0),
552
+ terminalError
553
+ } : {
554
+ events,
555
+ toolCalls: calls.map(toolCallFromGeminiFunctionCall),
556
+ hasToolCallMarker,
557
+ hasSyntheticToolCalls: calls.some((call) => call.callId === void 0),
558
+ providerFinishReason,
559
+ terminalError
560
+ };
507
561
  }
508
- function assistantContentFromGeminiResponse(response) {
509
- const parts = candidateParts(response);
562
+ var GeminiCompletionStreamState = class {
563
+ toolCalls = /* @__PURE__ */ new Map();
564
+ providerFinishReason;
565
+ terminalChunk;
566
+ finalResponse;
567
+ sawToolCallMarker = false;
568
+ sawSyntheticToolCallChunk = false;
569
+ terminalError;
570
+ accept(chunk, mapping) {
571
+ if (mapping.hasSyntheticToolCalls && this.sawSyntheticToolCallChunk) {
572
+ const toolCallId = mapping.toolCalls.find(
573
+ (toolCall) => toolCall.callId === void 0
574
+ )?.toolCallId;
575
+ throw toolCallId === void 0 ? new CompletionProviderOutputError({
576
+ kind: "invalid-tool-call",
577
+ usage: this.currentUsage()
578
+ }) : invalidGeminiToolCall(toolCallId, this.currentUsage());
579
+ }
580
+ if (this.providerFinishReason !== void 0 && (mapping.hasToolCallMarker || hasGeminiSemanticProgress(mapping.events))) {
581
+ throw new CompletionProviderOutputError({
582
+ kind: "invalid-tool-call",
583
+ finishReason: "other",
584
+ usage: this.currentUsage()
585
+ });
586
+ }
587
+ for (const toolCall of mapping.toolCalls) {
588
+ const existing = this.toolCalls.get(toolCall.toolCallId);
589
+ if (existing !== void 0) {
590
+ if (existing.callId === void 0 || toolCall.callId === void 0 || !sameGeminiToolCall(existing, toolCall)) {
591
+ throw invalidGeminiToolCall(toolCall.toolCallId, this.currentUsage());
592
+ }
593
+ continue;
594
+ }
595
+ this.toolCalls.set(toolCall.toolCallId, toolCall);
596
+ }
597
+ this.sawToolCallMarker ||= mapping.hasToolCallMarker;
598
+ this.sawSyntheticToolCallChunk ||= mapping.hasSyntheticToolCalls;
599
+ for (const event of mapping.events) {
600
+ if (event.type === "final") {
601
+ this.finalResponse = event.response;
602
+ }
603
+ }
604
+ this.terminalError ??= mapping.terminalError;
605
+ if (mapping.providerFinishReason !== void 0) {
606
+ if (this.providerFinishReason !== void 0 && this.providerFinishReason !== mapping.providerFinishReason) {
607
+ throw new CompletionProviderOutputError({
608
+ kind: "invalid-tool-call",
609
+ finishReason: "other",
610
+ usage: this.currentUsage()
611
+ });
612
+ }
613
+ this.providerFinishReason = mapping.providerFinishReason;
614
+ this.terminalChunk = chunk;
615
+ }
616
+ }
617
+ assertComplete() {
618
+ if (this.terminalError !== void 0) {
619
+ throw geminiProviderOutputErrorWithUsage(this.terminalError, this.currentUsage());
620
+ }
621
+ if (!this.sawToolCallMarker && this.toolCalls.size === 0) return;
622
+ if (this.providerFinishReason !== void 0) {
623
+ assertSafeGeminiToolFinishReason(this.providerFinishReason, this.currentUsage());
624
+ return;
625
+ }
626
+ const toolCallId = this.toolCalls.keys().next().value;
627
+ throw new CompletionProviderOutputError(
628
+ toolCallId === void 0 ? { kind: "incomplete-tool-call", usage: this.currentUsage() } : { kind: "incomplete-tool-call", toolCallId, usage: this.currentUsage() }
629
+ );
630
+ }
631
+ finalEvent() {
632
+ let response = this.finalResponse;
633
+ if (response === void 0) {
634
+ if (this.terminalChunk === void 0) {
635
+ return void 0;
636
+ }
637
+ const raw = isPlainObject2(this.terminalChunk) ? this.terminalChunk : {};
638
+ response = {
639
+ choice: [],
640
+ usage: usageFromGemini(raw.usageMetadata),
641
+ rawResponse: this.terminalChunk
642
+ };
643
+ const messageId = stringFrom(raw.responseId) ?? stringFrom(raw.id);
644
+ if (messageId !== void 0) response.messageId = messageId;
645
+ }
646
+ response = mergeGeminiStreamToolCalls(response, [...this.toolCalls.values()]);
647
+ if (this.providerFinishReason !== void 0) {
648
+ applyGeminiFinishReasonValue(response, this.providerFinishReason, this.toolCalls.size > 0);
649
+ }
650
+ assertSafeGeminiCompletionResponse(response);
651
+ return { type: "final", response };
652
+ }
653
+ currentUsage() {
654
+ if (this.finalResponse !== void 0) {
655
+ return this.finalResponse.usage;
656
+ }
657
+ const raw = isPlainObject2(this.terminalChunk) ? this.terminalChunk : {};
658
+ return usageFromGemini(raw.usageMetadata);
659
+ }
660
+ };
661
+ function hasGeminiSemanticProgress(events) {
662
+ return events.some(
663
+ (event) => event.type === "text_delta" || event.type === "reasoning_delta" || event.type === "tool_call_delta" || event.type === "tool_call" || event.type === "provider_tool_call"
664
+ );
665
+ }
666
+ function sameGeminiToolCall(left, right) {
667
+ return left.toolName === right.toolName && left.callId === right.callId && left.signature === right.signature && sameJsonValue(left.input, right.input);
668
+ }
669
+ function sameJsonValue(left, right) {
670
+ if (Object.is(left, right)) return true;
671
+ if (isJsonArray(left) || isJsonArray(right)) {
672
+ return isJsonArray(left) && isJsonArray(right) && left.length === right.length && left.every((value, index) => {
673
+ const rightValue = right[index];
674
+ return rightValue !== void 0 && sameJsonValue(value, rightValue);
675
+ });
676
+ }
677
+ if (left === null || right === null || typeof left !== "object" || typeof right !== "object") {
678
+ return false;
679
+ }
680
+ const leftKeys = Object.keys(left);
681
+ const rightKeys = Object.keys(right);
682
+ return leftKeys.length === rightKeys.length && leftKeys.every(
683
+ (key) => Object.hasOwn(right, key) && sameJsonValue(left[key], right[key])
684
+ );
685
+ }
686
+ function isJsonArray(value) {
687
+ return Array.isArray(value);
688
+ }
689
+ function assistantContentFromGeminiResponse(response, usage) {
690
+ const parts = candidateParts(response, usage);
691
+ const calls = functionCallsFromGeminiResponse(response, parts, usage);
510
692
  if (parts.length === 0) {
511
- const text = textFromGeminiResponse(response);
512
- return text.length > 0 ? [AssistantContent.text(text)] : [];
693
+ const choice2 = [];
694
+ const text = textFromGeminiResponse(response, parts);
695
+ if (text.length > 0) choice2.push({ type: "text", text });
696
+ choice2.push(...calls.map(toolCallFromGeminiFunctionCall));
697
+ return choice2;
513
698
  }
699
+ const callsByPartIndex = new Map(calls.map((call) => [call.partIndex, call]));
514
700
  const choice = [];
515
- for (const part of parts) {
701
+ for (const { index, part } of parts) {
516
702
  if (typeof part.text === "string" && part.text.length > 0) {
517
703
  if (part.thought === true) {
518
- choice.push(AssistantContent.reasoningSummary(part.text));
704
+ choice.push({
705
+ type: "reasoning",
706
+ text: part.text,
707
+ details: [{ type: "summary", text: part.text }]
708
+ });
519
709
  } else {
520
- const text = AssistantContent.text(part.text);
521
710
  const signature = thoughtSignatureFrom(part);
522
- if (signature !== void 0) {
523
- text.signature = signature;
524
- }
711
+ let text = {
712
+ type: "text",
713
+ text: part.text
714
+ };
715
+ if (signature !== void 0) text = { ...text, signature };
525
716
  choice.push(text);
526
717
  }
527
718
  }
528
- if (isPlainObject(part.functionCall)) {
529
- const call = functionCallFromGeminiPart(part.functionCall, part);
530
- if (call !== void 0) {
531
- const toolCall = AssistantContent.toolCall(
532
- call.id ?? crypto.randomUUID(),
533
- call.name,
534
- call.args,
535
- call.id
536
- );
537
- if (call.signature !== void 0) {
538
- toolCall.signature = call.signature;
539
- }
540
- choice.push(toolCall);
541
- }
719
+ const call = callsByPartIndex.get(index);
720
+ if (call !== void 0) {
721
+ choice.push(toolCallFromGeminiFunctionCall(call));
542
722
  }
543
723
  }
544
724
  return choice;
545
725
  }
546
- function textFromGeminiResponse(response) {
547
- if (typeof response.text === "string") {
548
- return response.text;
726
+ function textFromGeminiResponse(response, parts = candidateParts(response)) {
727
+ if (parts.length > 0) {
728
+ return parts.flatMap(
729
+ ({ part }) => part.thought !== true && typeof part.text === "string" ? [part.text] : []
730
+ ).join("");
549
731
  }
550
- return candidateParts(response).flatMap((part) => part.thought !== true && typeof part.text === "string" ? [part.text] : []).join("");
732
+ if (hasGeminiCandidatePayload(response)) {
733
+ return "";
734
+ }
735
+ const directText = ownDataProperty(response, "text");
736
+ return typeof directText === "string" ? directText : "";
551
737
  }
552
- function functionCallsFromGeminiResponse(response) {
553
- const directCalls = Array.isArray(response.functionCalls) ? response.functionCalls : Array.isArray(response.function_calls) ? response.function_calls : [];
554
- const partCalls = candidateParts(response).flatMap((part) => {
555
- if (!isPlainObject(part.functionCall)) {
556
- return [];
557
- }
558
- const call = functionCallFromGeminiPart(part.functionCall, part);
559
- return call === void 0 ? [] : [call];
560
- });
561
- const normalizedDirectCalls = directCalls.flatMap((call) => {
562
- if (!isPlainObject(call) || typeof call.name !== "string") {
563
- return [];
564
- }
565
- const normalized = {
566
- name: call.name,
567
- args: toJsonValue(call.args ?? {})
568
- };
569
- const id = stringFrom(call.id);
570
- const signature = thoughtSignatureFrom(call);
571
- if (id !== void 0) {
572
- normalized.id = id;
573
- }
574
- if (signature !== void 0) {
575
- normalized.signature = signature;
738
+ function functionCallsFromGeminiResponse(response, parts, usage) {
739
+ if (parts.length > 0) {
740
+ const calls2 = parts.flatMap(({ index, part }) => {
741
+ if (part.functionCall === void 0) {
742
+ return [];
743
+ }
744
+ if (!isPlainObject2(part.functionCall)) {
745
+ throw invalidGeminiToolCall(deterministicGeminiToolCallId(index), usage);
746
+ }
747
+ return [functionCallFromGeminiPart(part.functionCall, part, index, usage)];
748
+ });
749
+ assertDistinctGeminiFunctionCalls(calls2, usage);
750
+ return calls2;
751
+ }
752
+ if (hasGeminiCandidatePayload(response)) {
753
+ return [];
754
+ }
755
+ const camelCaseCalls = ownDataProperty(response, "functionCalls");
756
+ const snakeCaseCalls = ownDataProperty(response, "function_calls");
757
+ const directCalls = Array.isArray(camelCaseCalls) ? camelCaseCalls : Array.isArray(snakeCaseCalls) ? snakeCaseCalls : [];
758
+ const calls = directCalls.map((call, index) => {
759
+ if (!isPlainObject2(call)) {
760
+ throw invalidGeminiToolCall(deterministicGeminiToolCallId(index), usage);
576
761
  }
577
- return [normalized];
762
+ return functionCallFromGeminiPart(call, call, index, usage);
578
763
  });
579
- return [...normalizedDirectCalls, ...partCalls];
764
+ assertDistinctGeminiFunctionCalls(calls, usage);
765
+ return calls;
580
766
  }
581
- function functionCallFromGeminiPart(call, part) {
582
- if (typeof call.name !== "string") {
583
- return void 0;
767
+ function functionCallFromGeminiPart(call, part, partIndex, usage) {
768
+ const fallbackId = deterministicGeminiToolCallId(partIndex);
769
+ const rawCallId = call.id;
770
+ const callId = isNonblankString(rawCallId) ? rawCallId : void 0;
771
+ const toolCallId = callId ?? fallbackId;
772
+ if (rawCallId !== void 0 && callId === void 0) {
773
+ throw invalidGeminiToolCall(toolCallId, usage);
774
+ }
775
+ if (call.partialArgs !== void 0 || call.partial_args !== void 0 || call.willContinue !== void 0 || call.will_continue !== void 0) {
776
+ throw new CompletionProviderOutputError({
777
+ kind: "incomplete-tool-call",
778
+ toolCallId,
779
+ usage
780
+ });
781
+ }
782
+ const name = call.name;
783
+ if (!isNonblankString(name)) {
784
+ throw invalidGeminiToolCall(toolCallId, usage);
785
+ }
786
+ const args = call.args;
787
+ if (!isPlainObject2(args) || !isJsonValue(args)) {
788
+ throw invalidGeminiToolCallArguments(toolCallId, usage);
584
789
  }
585
790
  const normalized = {
586
- name: call.name,
587
- args: toJsonValue(call.args ?? {})
791
+ toolCallId,
792
+ name,
793
+ args,
794
+ partIndex
588
795
  };
589
- const id = stringFrom(call.id);
590
796
  const signature = thoughtSignatureFrom(part) ?? thoughtSignatureFrom(call);
591
- if (id !== void 0) {
592
- normalized.id = id;
797
+ if (callId !== void 0) {
798
+ return signature === void 0 ? { ...normalized, callId } : { ...normalized, callId, signature };
593
799
  }
594
- if (signature !== void 0) {
595
- normalized.signature = signature;
800
+ return signature === void 0 ? normalized : { ...normalized, signature };
801
+ }
802
+ function candidateParts(response, usage) {
803
+ const candidate = primaryGeminiCandidate(response);
804
+ if (candidate === void 0 || candidate.content === void 0) {
805
+ return [];
806
+ }
807
+ if (!isPlainObject2(candidate.content)) {
808
+ throw new CompletionProviderOutputError({ kind: "invalid-tool-call", usage });
596
809
  }
597
- return normalized;
810
+ if (candidate.content.parts === void 0) return [];
811
+ if (!Array.isArray(candidate.content.parts)) {
812
+ throw new CompletionProviderOutputError({ kind: "invalid-tool-call", usage });
813
+ }
814
+ if (candidate.content.parts.some((part) => !isPlainObject2(part))) {
815
+ throw new CompletionProviderOutputError({ kind: "invalid-tool-call", usage });
816
+ }
817
+ return candidate.content.parts.map((part, index) => ({
818
+ index,
819
+ part
820
+ }));
598
821
  }
599
- function candidateParts(response) {
600
- const candidates = Array.isArray(response.candidates) ? response.candidates : [];
601
- return candidates.flatMap((candidate) => {
602
- if (!isPlainObject(candidate) || !isPlainObject(candidate.content)) {
603
- return [];
822
+ function primaryGeminiCandidate(response) {
823
+ if (response.candidates === void 0) return void 0;
824
+ if (!Array.isArray(response.candidates)) {
825
+ throw new CompletionProviderOutputError({ kind: "invalid-tool-call" });
826
+ }
827
+ const candidates = response.candidates;
828
+ if (candidates.some(
829
+ (candidate2) => !isPlainObject2(candidate2) || candidate2.index !== void 0 && (!Number.isSafeInteger(candidate2.index) || candidate2.index < 0)
830
+ )) {
831
+ throw new CompletionProviderOutputError({ kind: "invalid-tool-call" });
832
+ }
833
+ const primaryCandidates = candidates.filter(
834
+ (candidate2) => isPlainObject2(candidate2) && candidate2.index === 0
835
+ );
836
+ if (primaryCandidates.length === 1) {
837
+ return primaryCandidates[0];
838
+ }
839
+ if (primaryCandidates.length > 1) {
840
+ throw new CompletionProviderOutputError({ kind: "invalid-tool-call" });
841
+ }
842
+ if (candidates.length === 0) return void 0;
843
+ if (candidates.length !== 1) {
844
+ throw new CompletionProviderOutputError({ kind: "invalid-tool-call" });
845
+ }
846
+ const candidate = candidates[0];
847
+ if (candidate.index !== void 0 && candidate.index !== 0) {
848
+ throw new CompletionProviderOutputError({ kind: "invalid-tool-call" });
849
+ }
850
+ return candidate;
851
+ }
852
+ function providerFinishReasonFromGeminiResponse(response) {
853
+ const candidateFinishReason = stringFrom(primaryGeminiCandidate(response)?.finishReason);
854
+ if (candidateFinishReason !== void 0) return candidateFinishReason;
855
+ const promptFeedback = response.promptFeedback ?? response.prompt_feedback;
856
+ if (promptFeedback === void 0) return void 0;
857
+ if (!isPlainObject2(promptFeedback)) {
858
+ throw new CompletionProviderOutputError({ kind: "invalid-response" });
859
+ }
860
+ const blockReason = promptFeedback.blockReason ?? promptFeedback.block_reason;
861
+ if (blockReason === void 0) return void 0;
862
+ if (typeof blockReason !== "string" || blockReason.length === 0) {
863
+ throw new CompletionProviderOutputError({ kind: "invalid-response" });
864
+ }
865
+ return blockReason;
866
+ }
867
+ function hasGeminiCandidatePayload(response) {
868
+ return Array.isArray(response.candidates) && response.candidates.length > 0;
869
+ }
870
+ function hasGeminiFunctionCallMarker(response, parts) {
871
+ if (parts.some(({ part }) => ownDataProperty(part, "functionCall") !== void 0)) {
872
+ return true;
873
+ }
874
+ if (hasGeminiCandidatePayload(response)) return false;
875
+ const camelCaseCalls = ownDataProperty(response, "functionCalls");
876
+ const snakeCaseCalls = ownDataProperty(response, "function_calls");
877
+ return Array.isArray(camelCaseCalls) && camelCaseCalls.length > 0 || Array.isArray(snakeCaseCalls) && snakeCaseCalls.length > 0;
878
+ }
879
+ function deterministicGeminiToolCallId(partIndex) {
880
+ return `gemini-tool-${partIndex.toString()}`;
881
+ }
882
+ function toolCallFromGeminiFunctionCall(call) {
883
+ let toolCall = {
884
+ type: "tool-call",
885
+ toolCallId: call.toolCallId,
886
+ toolName: call.name,
887
+ input: call.args
888
+ };
889
+ if (call.callId !== void 0) toolCall = { ...toolCall, callId: call.callId };
890
+ if (call.signature !== void 0) toolCall = { ...toolCall, signature: call.signature };
891
+ return toolCall;
892
+ }
893
+ function mergeGeminiStreamToolCalls(response, toolCalls) {
894
+ if (toolCalls.length === 0) return response;
895
+ const finalIds = new Set(
896
+ response.choice.flatMap((part) => part.type === "tool-call" ? [part.toolCallId] : [])
897
+ );
898
+ const missing = toolCalls.filter((toolCall) => !finalIds.has(toolCall.toolCallId));
899
+ return missing.length === 0 ? response : { ...response, choice: [...response.choice, ...missing] };
900
+ }
901
+ function assertSafeGeminiToolFinishReason(value, usage) {
902
+ const error = geminiToolFinishError(value, true, usage);
903
+ if (error !== void 0) throw error;
904
+ }
905
+ function geminiToolFinishError(value, hasToolCalls, usage) {
906
+ if (value === "MALFORMED_FUNCTION_CALL") {
907
+ return new CompletionProviderOutputError({ kind: "malformed-tool-arguments", usage });
908
+ }
909
+ if (value === "UNEXPECTED_TOOL_CALL" || value === "TOO_MANY_TOOL_CALLS") {
910
+ return new CompletionProviderOutputError({ kind: "invalid-tool-call", usage });
911
+ }
912
+ if (!hasToolCalls) return void 0;
913
+ if (value === void 0) {
914
+ return new CompletionProviderOutputError({ kind: "incomplete-tool-call", usage });
915
+ }
916
+ const finishReason = geminiFinishReason(value, true);
917
+ if (finishReason === "tool-calls") return void 0;
918
+ if (finishReason === "length") {
919
+ return new CompletionProviderOutputError({
920
+ kind: "truncated-tool-call",
921
+ finishReason,
922
+ usage
923
+ });
924
+ }
925
+ if (finishReason === "content-filter") {
926
+ return new CompletionProviderOutputError({
927
+ kind: "filtered-tool-call",
928
+ finishReason,
929
+ usage
930
+ });
931
+ }
932
+ return new CompletionProviderOutputError({ kind: "invalid-tool-call", finishReason, usage });
933
+ }
934
+ function assertSafeGeminiCompletionResponse(response) {
935
+ const toolCalls = response.choice.filter(
936
+ (part) => part.type === "tool-call"
937
+ );
938
+ if (toolCalls.length > 0) {
939
+ if (response.finishReason === void 0) {
940
+ throw new CompletionProviderOutputError({
941
+ kind: "incomplete-tool-call",
942
+ usage: response.usage
943
+ });
944
+ }
945
+ assertNormalizedGeminiToolFinishReason(response.finishReason, response.usage);
946
+ } else if (toolCalls.length === 0 && response.finishReason === "tool-calls") {
947
+ throw new CompletionProviderOutputError({
948
+ kind: "invalid-tool-call",
949
+ finishReason: response.finishReason,
950
+ usage: response.usage
951
+ });
952
+ }
953
+ const toolCallIds = /* @__PURE__ */ new Set();
954
+ const callIds = /* @__PURE__ */ new Set();
955
+ for (const toolCall of toolCalls) {
956
+ if (toolCallIds.has(toolCall.toolCallId)) {
957
+ throw invalidGeminiToolCall(toolCall.toolCallId, response.usage);
958
+ }
959
+ toolCallIds.add(toolCall.toolCallId);
960
+ if (toolCall.callId !== void 0) {
961
+ if (callIds.has(toolCall.callId)) {
962
+ throw invalidGeminiToolCall(toolCall.toolCallId, response.usage);
963
+ }
964
+ callIds.add(toolCall.callId);
965
+ }
966
+ }
967
+ }
968
+ function assertDistinctGeminiFunctionCalls(calls, usage) {
969
+ const toolCallIds = /* @__PURE__ */ new Set();
970
+ const callIds = /* @__PURE__ */ new Set();
971
+ for (const call of calls) {
972
+ if (toolCallIds.has(call.toolCallId)) {
973
+ throw invalidGeminiToolCall(call.toolCallId, usage);
974
+ }
975
+ toolCallIds.add(call.toolCallId);
976
+ if (call.callId !== void 0) {
977
+ if (callIds.has(call.callId)) {
978
+ throw invalidGeminiToolCall(call.toolCallId, usage);
979
+ }
980
+ callIds.add(call.callId);
604
981
  }
605
- return Array.isArray(candidate.content.parts) ? candidate.content.parts.filter(isPlainObject) : [];
982
+ }
983
+ }
984
+ function assertNormalizedGeminiToolFinishReason(finishReason, usage) {
985
+ if (finishReason === "stop" || finishReason === "tool-calls") return;
986
+ if (finishReason === "length") {
987
+ throw new CompletionProviderOutputError({
988
+ kind: "truncated-tool-call",
989
+ finishReason,
990
+ usage
991
+ });
992
+ }
993
+ if (finishReason === "content-filter") {
994
+ throw new CompletionProviderOutputError({
995
+ kind: "filtered-tool-call",
996
+ finishReason,
997
+ usage
998
+ });
999
+ }
1000
+ throw new CompletionProviderOutputError({ kind: "invalid-tool-call", finishReason, usage });
1001
+ }
1002
+ function geminiProviderOutputErrorWithUsage(error, usage) {
1003
+ if (error.kind === "truncated-tool-call") {
1004
+ return new CompletionProviderOutputError({
1005
+ kind: error.kind,
1006
+ finishReason: "length",
1007
+ toolCallId: error.toolCallId,
1008
+ usage
1009
+ });
1010
+ }
1011
+ if (error.kind === "filtered-tool-call") {
1012
+ return new CompletionProviderOutputError({
1013
+ kind: error.kind,
1014
+ finishReason: "content-filter",
1015
+ toolCallId: error.toolCallId,
1016
+ usage
1017
+ });
1018
+ }
1019
+ if (error.finishReason === "length" || error.finishReason === "content-filter") {
1020
+ throw error;
1021
+ }
1022
+ return new CompletionProviderOutputError({
1023
+ kind: error.kind,
1024
+ finishReason: error.finishReason,
1025
+ toolCallId: error.toolCallId,
1026
+ usage
1027
+ });
1028
+ }
1029
+ function invalidGeminiToolCall(toolCallId, usage) {
1030
+ return new CompletionProviderOutputError({ kind: "invalid-tool-call", toolCallId, usage });
1031
+ }
1032
+ function invalidGeminiToolCallArguments(toolCallId, usage) {
1033
+ return new CompletionProviderOutputError({
1034
+ kind: "invalid-tool-arguments",
1035
+ toolCallId,
1036
+ usage
606
1037
  });
607
1038
  }
1039
+ function ownDataProperty(value, key) {
1040
+ try {
1041
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
1042
+ return descriptor !== void 0 && "value" in descriptor ? descriptor.value : void 0;
1043
+ } catch {
1044
+ return void 0;
1045
+ }
1046
+ }
1047
+ function isNonblankString(value) {
1048
+ return typeof value === "string" && value.trim().length > 0;
1049
+ }
608
1050
  function usageFromGemini(usage) {
609
- const raw = isPlainObject(usage) ? usage : {};
1051
+ const raw = isPlainObject2(usage) ? usage : {};
610
1052
  const promptInputTokens = numberFrom(raw.promptTokenCount);
611
1053
  const toolInputTokens = numberFrom(raw.toolUsePromptTokenCount);
612
1054
  const inputTokens = promptInputTokens + toolInputTokens;
@@ -631,17 +1073,11 @@ function usageFromGemini(usage) {
631
1073
  }
632
1074
  };
633
1075
  }
634
- function toJsonValue(value) {
635
- if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || Array.isArray(value) || isPlainObject(value)) {
636
- return value;
637
- }
638
- return String(value);
639
- }
640
- function isPlainObject(value) {
1076
+ function isPlainObject2(value) {
641
1077
  return typeof value === "object" && value !== null && !Array.isArray(value);
642
1078
  }
643
1079
  function numberFrom(value) {
644
- return typeof value === "number" && Number.isFinite(value) ? value : 0;
1080
+ return typeof value === "number" && Number.isFinite(value) ? Math.max(0, value) : 0;
645
1081
  }
646
1082
  function stringFrom(value) {
647
1083
  return typeof value === "string" ? value : void 0;
@@ -661,36 +1097,41 @@ function toolCallDelta(id, values) {
661
1097
 
662
1098
  // src/gemini/embedding.ts
663
1099
  var GeminiEmbeddingModel = class {
664
- constructor(client, model, options = {}) {
1100
+ constructor(client, options) {
665
1101
  this.client = client;
666
- this.model = model;
1102
+ this.modelId = options.modelId;
667
1103
  this.dimensions = options.dimensions;
668
1104
  this.maxBatchSize = options.maxBatchSize ?? 100;
669
1105
  this.taskType = options.taskType;
670
1106
  this.title = options.title;
671
1107
  }
672
1108
  client;
673
- model;
1109
+ provider = "gemini";
1110
+ modelId;
674
1111
  dimensions;
675
1112
  maxBatchSize;
676
1113
  taskType;
677
1114
  title;
678
- async embedTexts(texts) {
1115
+ async embedTexts(texts, options) {
679
1116
  const embeddings = [];
680
1117
  for (let index = 0; index < texts.length; index += this.maxBatchSize) {
681
1118
  const batch = texts.slice(index, index + this.maxBatchSize);
682
- embeddings.push(...await this.embedBatch(batch));
1119
+ embeddings.push(...await this.embedBatch(batch, options));
683
1120
  }
684
1121
  return embeddings;
685
1122
  }
686
- async embedBatch(texts) {
1123
+ async embedBatch(texts, options) {
687
1124
  if (texts.length === 0) {
688
1125
  return [];
689
1126
  }
1127
+ const config = { ...this.embeddingConfig() };
1128
+ if (options?.abortSignal !== void 0) {
1129
+ Object.assign(config, { abortSignal: options.abortSignal });
1130
+ }
690
1131
  const response = await this.client.models.embedContent({
691
- model: this.model,
1132
+ model: this.modelId,
692
1133
  contents: texts,
693
- config: this.embeddingConfig()
1134
+ config: disableGeminiNativeRetries(config)
694
1135
  });
695
1136
  const rawEmbeddings = embeddingsFromResponse(response);
696
1137
  if (rawEmbeddings.length !== texts.length) {
@@ -740,54 +1181,60 @@ var GEMINI_2_5_FLASH_IMAGE = "gemini-2.5-flash-image";
740
1181
  var GEMINI_3_PRO_IMAGE_PREVIEW = "gemini-3-pro-image-preview";
741
1182
  var IMAGEN_4_GENERATE = "imagen-4.0-generate-001";
742
1183
  var GeminiImageGenerationModel = class {
743
- constructor(client, defaultModel = GEMINI_2_5_FLASH_IMAGE) {
1184
+ constructor(client, modelId) {
744
1185
  this.client = client;
745
- this.defaultModel = defaultModel;
1186
+ this.modelId = modelId;
746
1187
  }
747
1188
  client;
748
- defaultModel;
1189
+ modelId;
749
1190
  provider = "gemini";
750
- async imageGeneration(request) {
1191
+ async imageGeneration(request, options) {
1192
+ const providerOptions = isPlainObject3(request.providerOptions) ? request.providerOptions : {};
1193
+ const { config: providerConfigValue, ...providerTopLevel } = providerOptions;
1194
+ const providerConfig = isPlainObject3(providerConfigValue) ? providerConfigValue : {};
1195
+ const providerImageConfig = isPlainObject3(providerConfig.imageConfig) ? providerConfig.imageConfig : {};
1196
+ const config = {
1197
+ ...providerConfig,
1198
+ responseModalities: ["TEXT", "IMAGE"],
1199
+ imageConfig: {
1200
+ ...providerImageConfig,
1201
+ aspectRatio: aspectRatio(request.width, request.height)
1202
+ }
1203
+ };
1204
+ if (options?.abortSignal !== void 0) config.abortSignal = options.abortSignal;
751
1205
  const params = {
752
- model: this.defaultModel,
1206
+ ...providerTopLevel,
1207
+ model: this.modelId,
753
1208
  contents: request.prompt,
754
- config: {
755
- responseModalities: ["TEXT", "IMAGE"],
756
- imageConfig: { aspectRatio: aspectRatio(request.width, request.height) }
757
- }
1209
+ config: disableGeminiNativeRetries(config)
758
1210
  };
759
- if (isPlainObject2(request.additionalParams)) {
760
- const { config, ...topLevel } = request.additionalParams;
761
- Object.assign(params, topLevel);
762
- if (isPlainObject2(config)) {
763
- params.config = { ...params.config, ...config };
764
- }
765
- }
766
1211
  const response = await this.client.models.generateContent(params);
767
1212
  return nativeImageResponseFromGemini(response);
768
1213
  }
769
1214
  };
770
1215
  var GeminiImagenGenerationModel = class {
771
- constructor(client, defaultModel = IMAGEN_4_GENERATE) {
1216
+ constructor(client, modelId) {
772
1217
  this.client = client;
773
- this.defaultModel = defaultModel;
1218
+ this.modelId = modelId;
774
1219
  }
775
1220
  client;
776
- defaultModel;
1221
+ modelId;
777
1222
  provider = "gemini";
778
- async imageGeneration(request) {
1223
+ async imageGeneration(request, options) {
1224
+ const providerOptions = isPlainObject3(request.providerOptions) ? request.providerOptions : {};
1225
+ const { config: providerConfigValue, ...providerTopLevel } = providerOptions;
1226
+ const providerConfig = isPlainObject3(providerConfigValue) ? providerConfigValue : {};
1227
+ const config = {
1228
+ ...providerConfig,
1229
+ aspectRatio: aspectRatio(request.width, request.height)
1230
+ };
1231
+ if (options?.abortSignal !== void 0) config.abortSignal = options.abortSignal;
779
1232
  const params = {
780
- model: this.defaultModel,
1233
+ ...providerTopLevel,
1234
+ model: this.modelId,
781
1235
  prompt: request.prompt,
782
- config: { aspectRatio: aspectRatio(request.width, request.height) }
1236
+ config: disableGeminiNativeRetries(config)
783
1237
  };
784
- if (isPlainObject2(request.additionalParams)) {
785
- const { config, ...topLevel } = request.additionalParams;
786
- Object.assign(params, topLevel);
787
- if (isPlainObject2(config)) {
788
- params.config = { ...params.config, ...config };
789
- }
790
- }
791
1238
  const response = await this.client.models.generateImages(params);
792
1239
  return imagenResponseFromGemini(response);
793
1240
  }
@@ -796,12 +1243,12 @@ function nativeImageResponseFromGemini(response) {
796
1243
  const raw = response;
797
1244
  const candidates = Array.isArray(raw.candidates) ? raw.candidates : [];
798
1245
  const images = candidates.flatMap((candidate) => {
799
- if (!isPlainObject2(candidate) || !isPlainObject2(candidate.content)) {
1246
+ if (!isPlainObject3(candidate) || !isPlainObject3(candidate.content)) {
800
1247
  return [];
801
1248
  }
802
1249
  const parts = Array.isArray(candidate.content.parts) ? candidate.content.parts : [];
803
1250
  return parts.flatMap((part) => {
804
- if (!isPlainObject2(part) || !isPlainObject2(part.inlineData)) {
1251
+ if (!isPlainObject3(part) || !isPlainObject3(part.inlineData)) {
805
1252
  return [];
806
1253
  }
807
1254
  const data = part.inlineData.data;
@@ -816,14 +1263,11 @@ function nativeImageResponseFromGemini(response) {
816
1263
  ];
817
1264
  });
818
1265
  });
819
- const image = images[0]?.data;
820
- if (image === void 0) {
1266
+ if (images.length === 0) {
821
1267
  throw new Error("Gemini image generation response contained no inline image data.");
822
1268
  }
823
1269
  return {
824
- image,
825
1270
  images,
826
- mediaType: images[0]?.mediaType,
827
1271
  rawResponse: response
828
1272
  };
829
1273
  }
@@ -831,7 +1275,7 @@ function imagenResponseFromGemini(response) {
831
1275
  const raw = response;
832
1276
  const images = (Array.isArray(raw.generatedImages) ? raw.generatedImages : []).flatMap(
833
1277
  (item) => {
834
- if (!isPlainObject2(item) || !isPlainObject2(item.image)) {
1278
+ if (!isPlainObject3(item) || !isPlainObject3(item.image)) {
835
1279
  return [];
836
1280
  }
837
1281
  const imageBytes = item.image.imageBytes;
@@ -846,14 +1290,11 @@ function imagenResponseFromGemini(response) {
846
1290
  ];
847
1291
  }
848
1292
  );
849
- const image = images[0]?.data;
850
- if (image === void 0) {
1293
+ if (images.length === 0) {
851
1294
  throw new Error("Gemini image generation response contained no base64 images.");
852
1295
  }
853
1296
  return {
854
- image,
855
1297
  images,
856
- mediaType: images[0]?.mediaType,
857
1298
  rawResponse: response
858
1299
  };
859
1300
  }
@@ -882,50 +1323,114 @@ function decodeBase64Image(value) {
882
1323
  }
883
1324
  return new Uint8Array(bytes);
884
1325
  }
885
- function isPlainObject2(value) {
1326
+ function isPlainObject3(value) {
886
1327
  return typeof value === "object" && value !== null && !Array.isArray(value);
887
1328
  }
888
1329
 
1330
+ // src/gemini/models.ts
1331
+ var CONTEXT_1M_64K = {
1332
+ contextWindow: 1048576,
1333
+ maxInputTokens: 1048576,
1334
+ maxOutputTokens: 65536
1335
+ };
1336
+ var GEMINI_COMPLETION_MODEL_CONTEXT_LIMITS = {
1337
+ "gemini-2.0-flash": {
1338
+ contextWindow: 1048576,
1339
+ maxInputTokens: 1048576,
1340
+ maxOutputTokens: 8192
1341
+ },
1342
+ "gemini-2.0-flash-lite": {
1343
+ contextWindow: 1048576,
1344
+ maxInputTokens: 1048576,
1345
+ maxOutputTokens: 8192
1346
+ },
1347
+ "gemini-2.5-flash": CONTEXT_1M_64K,
1348
+ "gemini-2.5-flash-image": {
1349
+ contextWindow: 32768,
1350
+ maxInputTokens: 32768,
1351
+ maxOutputTokens: 32768
1352
+ },
1353
+ "gemini-2.5-flash-lite": CONTEXT_1M_64K,
1354
+ "gemini-2.5-flash-preview-tts": {
1355
+ contextWindow: 8192,
1356
+ maxInputTokens: 8192,
1357
+ maxOutputTokens: 16384
1358
+ },
1359
+ "gemini-2.5-pro": CONTEXT_1M_64K,
1360
+ "gemini-2.5-pro-preview-tts": {
1361
+ contextWindow: 8192,
1362
+ maxInputTokens: 8192,
1363
+ maxOutputTokens: 16384
1364
+ },
1365
+ "gemini-3-flash-preview": CONTEXT_1M_64K,
1366
+ "gemini-3-pro-image-preview": {
1367
+ contextWindow: 131072,
1368
+ maxInputTokens: 131072,
1369
+ maxOutputTokens: 32768
1370
+ },
1371
+ "gemini-3-pro-preview": CONTEXT_1M_64K,
1372
+ "gemini-3.1-flash-image-preview": {
1373
+ contextWindow: 65536,
1374
+ maxInputTokens: 65536,
1375
+ maxOutputTokens: 65536
1376
+ },
1377
+ "gemini-3.1-flash-lite": CONTEXT_1M_64K,
1378
+ "gemini-3.1-flash-lite-preview": CONTEXT_1M_64K,
1379
+ "gemini-3.1-pro-preview": CONTEXT_1M_64K,
1380
+ "gemini-3.1-pro-preview-customtools": CONTEXT_1M_64K,
1381
+ "gemini-3.5-flash": CONTEXT_1M_64K,
1382
+ "gemini-flash-latest": CONTEXT_1M_64K,
1383
+ "gemini-flash-lite-latest": CONTEXT_1M_64K,
1384
+ "gemma-4-26b-a4b-it": {
1385
+ contextWindow: 262144,
1386
+ maxInputTokens: 262144,
1387
+ maxOutputTokens: 32768
1388
+ },
1389
+ "gemma-4-31b-it": {
1390
+ contextWindow: 262144,
1391
+ maxInputTokens: 262144,
1392
+ maxOutputTokens: 32768
1393
+ }
1394
+ };
1395
+
889
1396
  // src/gemini/transcription.ts
890
1397
  import { Buffer as Buffer3 } from "buffer";
891
1398
  var TRANSCRIPTION_PREAMBLE = "Transcribe the provided audio exactly. Do not add additional information.";
892
1399
  var GeminiTranscriptionModel = class {
893
- constructor(client, defaultModel = "gemini-2.5-flash") {
1400
+ constructor(client, modelId) {
894
1401
  this.client = client;
895
- this.defaultModel = defaultModel;
1402
+ this.modelId = modelId;
896
1403
  }
897
1404
  client;
898
- defaultModel;
1405
+ modelId;
899
1406
  provider = "gemini";
900
- async transcription(request) {
901
- const config = {};
1407
+ async transcription(request, options) {
1408
+ const config = isPlainObject4(request.providerOptions) ? { ...request.providerOptions } : {};
902
1409
  if (request.temperature !== void 0) {
903
1410
  config.temperature = request.temperature;
904
1411
  }
905
- if (isPlainObject3(request.additionalParams)) {
906
- Object.assign(config, request.additionalParams);
907
- }
1412
+ if (options?.abortSignal !== void 0) config.abortSignal = options.abortSignal;
908
1413
  const response = await this.client.models.generateContent({
909
- model: this.defaultModel,
1414
+ model: this.modelId,
910
1415
  contents: [
911
1416
  {
912
1417
  role: "user",
913
1418
  parts: [
914
1419
  {
915
1420
  inlineData: {
916
- mimeType: mimeTypeFromFilename(request.filename),
1421
+ mimeType: request.mediaType ?? mimeTypeFromFilename(request.filename),
917
1422
  data: Buffer3.from(request.data).toString("base64")
918
1423
  }
919
1424
  }
920
1425
  ]
921
1426
  }
922
1427
  ],
923
- config: {
1428
+ config: disableGeminiNativeRetries({
924
1429
  ...config,
925
1430
  systemInstruction: request.prompt === void 0 ? TRANSCRIPTION_PREAMBLE : `${TRANSCRIPTION_PREAMBLE}
926
1431
 
927
1432
  ${request.prompt}`
928
- }
1433
+ })
929
1434
  });
930
1435
  return {
931
1436
  text: textFromGenerateContentResponse(response),
@@ -940,12 +1445,12 @@ function textFromGenerateContentResponse(response) {
940
1445
  }
941
1446
  const candidates = Array.isArray(raw.candidates) ? raw.candidates : [];
942
1447
  for (const candidate of candidates) {
943
- if (!isPlainObject3(candidate) || !isPlainObject3(candidate.content)) {
1448
+ if (!isPlainObject4(candidate) || !isPlainObject4(candidate.content)) {
944
1449
  continue;
945
1450
  }
946
1451
  const parts = Array.isArray(candidate.content.parts) ? candidate.content.parts : [];
947
1452
  for (const part of parts) {
948
- if (isPlainObject3(part) && typeof part.text === "string") {
1453
+ if (isPlainObject4(part) && typeof part.text === "string") {
949
1454
  return part.text;
950
1455
  }
951
1456
  }
@@ -962,34 +1467,55 @@ function mimeTypeFromFilename(filename) {
962
1467
  if (lower.endsWith(".opus")) return "audio/opus";
963
1468
  return "audio/mpeg";
964
1469
  }
965
- function isPlainObject3(value) {
1470
+ function isPlainObject4(value) {
966
1471
  return typeof value === "object" && value !== null && !Array.isArray(value);
967
1472
  }
968
1473
 
969
1474
  // src/gemini/client.ts
970
1475
  var GeminiClient = class {
971
- client;
972
- constructor(options = {}) {
973
- this.client = options.client ?? new GoogleGenAI(toGoogleGenAIOptions(options));
974
- }
975
- completionModel(model = "gemini-2.5-flash") {
976
- return new GeminiCompletionModel(this.client, model);
977
- }
978
- embeddingModel(model = "gemini-embedding-001", options = {}) {
979
- return new GeminiEmbeddingModel(this.client, model, options);
1476
+ sdk;
1477
+ constructor(options) {
1478
+ if (options.client !== void 0) {
1479
+ rejectManagedOptionsWithInjectedClient(options, ["apiKey", "vertexAi"]);
1480
+ this.sdk = options.client;
1481
+ return;
1482
+ }
1483
+ this.sdk = new GoogleGenAI(toGoogleGenAIOptions(options));
1484
+ }
1485
+ completionModel(options) {
1486
+ const modelId = requireModelId(options.modelId);
1487
+ return new GeminiCompletionModel(
1488
+ this.sdk,
1489
+ modelId,
1490
+ resolveModelContextLimits(
1491
+ modelId,
1492
+ GEMINI_COMPLETION_MODEL_CONTEXT_LIMITS,
1493
+ options.contextLimits
1494
+ )
1495
+ );
980
1496
  }
981
- imageGenerationModel(model = GEMINI_2_5_FLASH_IMAGE) {
982
- return new GeminiImageGenerationModel(this.client, model);
1497
+ embeddingModel(options) {
1498
+ requireModelId(options.modelId);
1499
+ validateOptionalPositiveSafeInteger(options.dimensions, "dimensions");
1500
+ validateOptionalPositiveSafeInteger(options.maxBatchSize, "maxBatchSize");
1501
+ return new GeminiEmbeddingModel(this.sdk, options);
983
1502
  }
984
- imagenGenerationModel(model = IMAGEN_4_GENERATE) {
985
- return new GeminiImagenGenerationModel(this.client, model);
1503
+ imageGenerationModel(options) {
1504
+ const modelId = requireModelId(options.modelId);
1505
+ return options.api === "generateContent" ? new GeminiImageGenerationModel(this.sdk, modelId) : new GeminiImagenGenerationModel(this.sdk, modelId);
986
1506
  }
987
- transcriptionModel(model = "gemini-2.5-flash") {
988
- return new GeminiTranscriptionModel(this.client, model);
1507
+ transcriptionModel(options) {
1508
+ return new GeminiTranscriptionModel(this.sdk, requireModelId(options.modelId));
989
1509
  }
990
- async listModels() {
1510
+ async listModels(options = {}) {
991
1511
  try {
992
- const response = await this.client.models.list({ config: { pageSize: 1e3 } });
1512
+ const config = { pageSize: 1e3 };
1513
+ if (options.abortSignal !== void 0) {
1514
+ Object.assign(config, { abortSignal: options.abortSignal });
1515
+ }
1516
+ const response = await this.sdk.models.list({
1517
+ config: disableGeminiNativeRetries(config)
1518
+ });
993
1519
  const data = (await collectModelsFromResponse(response)).map(toListedModel).filter(isListedModel);
994
1520
  return { data };
995
1521
  } catch (error) {
@@ -997,25 +1523,48 @@ var GeminiClient = class {
997
1523
  }
998
1524
  }
999
1525
  };
1526
+ function rejectManagedOptionsWithInjectedClient(options, keys) {
1527
+ const conflict = keys.find((key) => key in options);
1528
+ if (conflict !== void 0) {
1529
+ throw new TypeError(`GeminiClient cannot combine client with ${conflict}.`);
1530
+ }
1531
+ }
1000
1532
  function toGoogleGenAIOptions(options) {
1001
- if (options.vertexai === true) {
1002
- return {
1533
+ if ("client" in options && options.client !== void 0) {
1534
+ throw new TypeError("Injected Gemini clients do not have managed SDK options.");
1535
+ }
1536
+ if ("vertexAi" in options && options.vertexAi !== void 0) {
1537
+ const sdkOptions = {
1003
1538
  vertexai: true,
1004
- project: requireOption(options.project, "project", "Vertex Gemini"),
1005
- location: requireOption(options.location, "location", "Vertex Gemini"),
1006
- ...options.googleAuthOptions === void 0 ? {} : { googleAuthOptions: options.googleAuthOptions }
1539
+ project: requireOption(options.vertexAi.projectId, "projectId", "Vertex Gemini"),
1540
+ location: requireOption(options.vertexAi.location, "location", "Vertex Gemini")
1007
1541
  };
1542
+ if (options.vertexAi.googleAuthOptions !== void 0) {
1543
+ sdkOptions.googleAuthOptions = options.vertexAi.googleAuthOptions;
1544
+ }
1545
+ return sdkOptions;
1008
1546
  }
1009
1547
  return {
1010
1548
  apiKey: requireOption(options.apiKey, "apiKey", "Gemini")
1011
1549
  };
1012
1550
  }
1013
1551
  function requireOption(value, name, label) {
1014
- if (value === void 0 || value.length === 0) {
1552
+ if (value === void 0 || value.trim().length === 0) {
1015
1553
  throw new Error(`Missing ${label} ${name}. Pass ${name} when constructing GeminiClient.`);
1016
1554
  }
1017
1555
  return value;
1018
1556
  }
1557
+ function requireModelId(modelId) {
1558
+ if (modelId.trim().length === 0) {
1559
+ throw new TypeError("modelId must be a non-empty string");
1560
+ }
1561
+ return modelId;
1562
+ }
1563
+ function validateOptionalPositiveSafeInteger(value, name) {
1564
+ if (value !== void 0 && (!Number.isSafeInteger(value) || value <= 0)) {
1565
+ throw new TypeError(`${name} must be a positive safe integer`);
1566
+ }
1567
+ }
1019
1568
  async function collectModelsFromResponse(response) {
1020
1569
  if (isAsyncIterable(response)) {
1021
1570
  const models = [];
@@ -1116,11 +1665,6 @@ export {
1116
1665
  GEMINI_2_5_FLASH_IMAGE,
1117
1666
  GEMINI_3_PRO_IMAGE_PREVIEW,
1118
1667
  GeminiClient,
1119
- GeminiCompletionModel,
1120
- GeminiEmbeddingModel,
1121
- GeminiImageGenerationModel,
1122
- GeminiImagenGenerationModel,
1123
- GeminiTranscriptionModel,
1124
1668
  IMAGEN_4_GENERATE,
1125
1669
  gemini_exports as gemini
1126
1670
  };