@ai-sdk/google 4.0.86 → 4.0.88
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/CHANGELOG.md +22 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +75 -30
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +2 -1
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +67 -25
- package/dist/internal/index.js.map +1 -1
- package/docs/15-google.mdx +10 -10
- package/package.json +3 -3
- package/src/google-language-model.ts +79 -4
- package/src/google-provider.ts +13 -7
- package/src/google-speech-api.ts +1 -0
- package/src/google-speech-model.ts +3 -0
- package/src/transcription/google-transcription-model.ts +4 -2
package/docs/15-google.mdx
CHANGED
|
@@ -2393,18 +2393,18 @@ Older models continue to use labelled transcripts, such as
|
|
|
2393
2393
|
| `gemini-3.8-flash-tts` | <Check /> | <Check /> |
|
|
2394
2394
|
| `gemini-3.8-flash-lite-tts` | <Check /> | <Check /> |
|
|
2395
2395
|
|
|
2396
|
-
##
|
|
2396
|
+
## Decision Models
|
|
2397
2397
|
|
|
2398
|
-
Create an experimental
|
|
2398
|
+
Create an experimental decision model with `google.decisionModel(modelId)`.
|
|
2399
2399
|
It uses Gemini structured output for Choice, Score, and Boolean questions. Choose a model
|
|
2400
2400
|
that supports structured output, such as `gemini-3.5-flash-lite`.
|
|
2401
2401
|
|
|
2402
2402
|
```ts
|
|
2403
2403
|
import { google } from '@ai-sdk/google';
|
|
2404
|
-
import {
|
|
2404
|
+
import { experimental_decide } from 'ai';
|
|
2405
2405
|
|
|
2406
|
-
const { answers } = await
|
|
2407
|
-
model: google.
|
|
2406
|
+
const { answers } = await experimental_decide({
|
|
2407
|
+
model: google.decisionModel('gemini-3.5-flash-lite'),
|
|
2408
2408
|
state: 'I was charged twice.',
|
|
2409
2409
|
questions: {
|
|
2410
2410
|
requestsRefund: {
|
|
@@ -2436,10 +2436,10 @@ and rejects safety-blocked, truncated, or invalid output. It preserves usage
|
|
|
2436
2436
|
Choice and Score answers do not include probability distributions. Boolean
|
|
2437
2437
|
answers contain prompted estimates of P(true), validated to be finite and in
|
|
2438
2438
|
`[0, 1]`. These estimates are not guaranteed to be calibrated. Apply thresholds
|
|
2439
|
-
in application code, for example `answers.requestsRefund.probability >= 0.5`. See [
|
|
2439
|
+
in application code, for example `answers.requestsRefund.probability >= 0.5`. See [Decisions](/docs/ai-sdk-core/decisions).
|
|
2440
2440
|
|
|
2441
|
-
|
|
2442
|
-
`createProviderRegistry().
|
|
2441
|
+
Decision models can also be accessed through `customProvider` aliases or
|
|
2442
|
+
`createProviderRegistry().decisionModel('provider:model')`. Direct string IDs
|
|
2443
2443
|
use Gateway by default, or an explicitly configured default provider with an
|
|
2444
|
-
`
|
|
2445
|
-
[model aliases and registries](/docs/ai-sdk-core/
|
|
2444
|
+
`decisionModel` method. See
|
|
2445
|
+
[model aliases and registries](/docs/ai-sdk-core/decisions#model-aliases-and-registries).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/google",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.88",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@ai-sdk/provider": "4.0.
|
|
39
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
38
|
+
"@ai-sdk/provider": "4.0.22",
|
|
39
|
+
"@ai-sdk/provider-utils": "5.0.54"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@ai-sdk/test-server": "2.0.3",
|
|
@@ -2,6 +2,7 @@ import type {
|
|
|
2
2
|
LanguageModelV4,
|
|
3
3
|
LanguageModelV4CallOptions,
|
|
4
4
|
LanguageModelV4Content,
|
|
5
|
+
LanguageModelV4FunctionTool,
|
|
5
6
|
LanguageModelV4FinishReason,
|
|
6
7
|
LanguageModelV4GenerateResult,
|
|
7
8
|
LanguageModelV4Source,
|
|
@@ -13,6 +14,7 @@ import type {
|
|
|
13
14
|
} from '@ai-sdk/provider';
|
|
14
15
|
import {
|
|
15
16
|
combineHeaders,
|
|
17
|
+
convertJsonResponseToolStream,
|
|
16
18
|
createToolNameMapping,
|
|
17
19
|
createEventSourceResponseHandler,
|
|
18
20
|
createJsonResponseHandler,
|
|
@@ -448,16 +450,57 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
448
450
|
};
|
|
449
451
|
}
|
|
450
452
|
|
|
451
|
-
private getArgs(
|
|
453
|
+
private async getArgs(
|
|
452
454
|
options: LanguageModelV4CallOptions,
|
|
453
455
|
{ isStreaming = false }: { isStreaming?: boolean } = {},
|
|
454
456
|
) {
|
|
455
|
-
|
|
457
|
+
const { responseFormat, tools, toolChoice } = options;
|
|
458
|
+
let jsonResponseTool: LanguageModelV4FunctionTool | undefined;
|
|
459
|
+
// Gemini models before Gemini 3 reject JSON response formatting together
|
|
460
|
+
// with function tools. Gemini 3 supports the combination only with automatic
|
|
461
|
+
// tool choice (AUTO). Forced tool choice (ANY) requires a JSON response tool.
|
|
462
|
+
if (
|
|
463
|
+
responseFormat?.type === 'json' &&
|
|
464
|
+
responseFormat.schema != null &&
|
|
465
|
+
tools?.some(tool => tool.type === 'function') &&
|
|
466
|
+
/(^|\/)gemini-/i.test(this.modelId) &&
|
|
467
|
+
(!getGoogleModelCapabilities(this.modelId).usesGemini3Features ||
|
|
468
|
+
toolChoice?.type === 'required' ||
|
|
469
|
+
toolChoice?.type === 'tool')
|
|
470
|
+
) {
|
|
471
|
+
let name = 'json';
|
|
472
|
+
for (let suffix = 1; tools.some(tool => tool.name === name); suffix++) {
|
|
473
|
+
name = `json_${suffix}`;
|
|
474
|
+
}
|
|
475
|
+
jsonResponseTool = {
|
|
476
|
+
type: 'function',
|
|
477
|
+
name,
|
|
478
|
+
description:
|
|
479
|
+
responseFormat.description ?? 'Respond with a JSON object.',
|
|
480
|
+
inputSchema: responseFormat.schema,
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
const prepared = await GoogleLanguageModel.prepareRequest({
|
|
456
485
|
modelId: this.modelId,
|
|
457
486
|
config: this.config,
|
|
458
|
-
options
|
|
487
|
+
options:
|
|
488
|
+
jsonResponseTool == null
|
|
489
|
+
? options
|
|
490
|
+
: {
|
|
491
|
+
...options,
|
|
492
|
+
responseFormat: undefined,
|
|
493
|
+
tools: [...(tools ?? []), jsonResponseTool],
|
|
494
|
+
toolChoice:
|
|
495
|
+
toolChoice?.type === 'tool'
|
|
496
|
+
? toolChoice
|
|
497
|
+
: toolChoice?.type === 'none'
|
|
498
|
+
? { type: 'tool', toolName: jsonResponseTool.name }
|
|
499
|
+
: { type: 'required' },
|
|
500
|
+
},
|
|
459
501
|
isStreaming,
|
|
460
502
|
});
|
|
503
|
+
return { ...prepared, jsonResponseToolName: jsonResponseTool?.name };
|
|
461
504
|
}
|
|
462
505
|
|
|
463
506
|
static convertGenerateContentResponse({
|
|
@@ -466,12 +509,14 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
466
509
|
warnings,
|
|
467
510
|
providerOptionsNames,
|
|
468
511
|
toolNameMapping,
|
|
512
|
+
jsonResponseToolName,
|
|
469
513
|
}: {
|
|
470
514
|
config: GoogleLanguageModelConfig;
|
|
471
515
|
response: InferSchema<typeof responseSchema>;
|
|
472
516
|
warnings: SharedV4Warning[];
|
|
473
517
|
providerOptionsNames: readonly string[];
|
|
474
518
|
toolNameMapping?: ReturnType<typeof createToolNameMapping>;
|
|
519
|
+
jsonResponseToolName?: string;
|
|
475
520
|
}): LanguageModelV4GenerateResult {
|
|
476
521
|
const wrapProviderMetadata = (payload: Record<string, unknown>) =>
|
|
477
522
|
Object.fromEntries(
|
|
@@ -529,6 +574,7 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
529
574
|
},
|
|
530
575
|
});
|
|
531
576
|
} else if ('text' in part && part.text != null) {
|
|
577
|
+
if (jsonResponseToolName != null && part.thought !== true) continue;
|
|
532
578
|
const thoughtSignatureMetadata = part.thoughtSignature
|
|
533
579
|
? wrapProviderMetadata({
|
|
534
580
|
thoughtSignature: part.thoughtSignature,
|
|
@@ -548,6 +594,23 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
548
594
|
});
|
|
549
595
|
}
|
|
550
596
|
} else if ('functionCall' in part && part.functionCall.name != null) {
|
|
597
|
+
if (part.functionCall.name === jsonResponseToolName) {
|
|
598
|
+
content.push({
|
|
599
|
+
type: 'text',
|
|
600
|
+
text:
|
|
601
|
+
typeof part.functionCall.args === 'string'
|
|
602
|
+
? part.functionCall.args
|
|
603
|
+
: JSON.stringify(part.functionCall.args ?? {}),
|
|
604
|
+
...(part.thoughtSignature
|
|
605
|
+
? {
|
|
606
|
+
providerMetadata: wrapProviderMetadata({
|
|
607
|
+
thoughtSignature: part.thoughtSignature,
|
|
608
|
+
}),
|
|
609
|
+
}
|
|
610
|
+
: {}),
|
|
611
|
+
});
|
|
612
|
+
continue;
|
|
613
|
+
}
|
|
551
614
|
content.push({
|
|
552
615
|
type: 'tool-call' as const,
|
|
553
616
|
toolCallId: part.functionCall.id || config.generateId(),
|
|
@@ -666,6 +729,7 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
666
729
|
providerOptionsNames,
|
|
667
730
|
extraHeaders,
|
|
668
731
|
toolNameMapping,
|
|
732
|
+
jsonResponseToolName,
|
|
669
733
|
} = await this.getArgs(options);
|
|
670
734
|
|
|
671
735
|
const mergedHeaders = combineHeaders(
|
|
@@ -696,6 +760,7 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
696
760
|
warnings,
|
|
697
761
|
providerOptionsNames,
|
|
698
762
|
toolNameMapping,
|
|
763
|
+
jsonResponseToolName,
|
|
699
764
|
});
|
|
700
765
|
|
|
701
766
|
return {
|
|
@@ -718,6 +783,7 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
718
783
|
providerOptionsNames,
|
|
719
784
|
extraHeaders,
|
|
720
785
|
toolNameMapping,
|
|
786
|
+
jsonResponseToolName,
|
|
721
787
|
} = await this.getArgs(options, { isStreaming: true });
|
|
722
788
|
const wrapProviderMetadata = (payload: Record<string, unknown>) =>
|
|
723
789
|
Object.fromEntries(
|
|
@@ -813,7 +879,7 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
813
879
|
hasToolCalls = true;
|
|
814
880
|
};
|
|
815
881
|
|
|
816
|
-
|
|
882
|
+
const result = {
|
|
817
883
|
stream: response.pipeThrough(
|
|
818
884
|
new TransformStream<
|
|
819
885
|
ParseResult<ChunkSchema>,
|
|
@@ -1301,6 +1367,15 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
1301
1367
|
response: { headers: responseHeaders },
|
|
1302
1368
|
request: { body: args },
|
|
1303
1369
|
};
|
|
1370
|
+
return {
|
|
1371
|
+
...result,
|
|
1372
|
+
stream:
|
|
1373
|
+
jsonResponseToolName == null
|
|
1374
|
+
? result.stream
|
|
1375
|
+
: result.stream.pipeThrough(
|
|
1376
|
+
convertJsonResponseToolStream(jsonResponseToolName),
|
|
1377
|
+
),
|
|
1378
|
+
};
|
|
1304
1379
|
}
|
|
1305
1380
|
}
|
|
1306
1381
|
|
package/src/google-provider.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
EmbeddingModelV4,
|
|
3
3
|
Experimental_BatchV4 as BatchV4,
|
|
4
|
-
|
|
4
|
+
Experimental_DecisionModelV4 as DecisionModelV4,
|
|
5
5
|
Experimental_VideoModelV4,
|
|
6
6
|
FilesV4,
|
|
7
7
|
ImageModelV4,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
type FetchFunction,
|
|
22
22
|
type WebSocketConstructor,
|
|
23
23
|
} from '@ai-sdk/provider-utils';
|
|
24
|
-
import {
|
|
24
|
+
import { Experimental_DecisionLanguageModel as DecisionLanguageModel } from '@ai-sdk/provider-utils/experimental-decision';
|
|
25
25
|
import { VERSION } from './version';
|
|
26
26
|
import { GoogleEmbeddingModel } from './google-embedding-model';
|
|
27
27
|
import type { GoogleEmbeddingModelId } from './google-embedding-model-options';
|
|
@@ -63,8 +63,12 @@ export interface GoogleProvider extends ProviderV4 {
|
|
|
63
63
|
|
|
64
64
|
chat(modelId: GoogleModelId): LanguageModelV4;
|
|
65
65
|
|
|
66
|
-
/** Creates an experimental Choice/Score/Boolean
|
|
67
|
-
|
|
66
|
+
/** Creates an experimental Choice/Score/Boolean decision model using Gemini. */
|
|
67
|
+
decisionModel(modelId: GoogleModelId): DecisionModelV4;
|
|
68
|
+
/** @deprecated Use `decisionModel` instead. */
|
|
69
|
+
evaluationModel(modelId: GoogleModelId): DecisionModelV4 & {
|
|
70
|
+
doEvaluate: DecisionModelV4['doDecide'];
|
|
71
|
+
};
|
|
68
72
|
|
|
69
73
|
experimental_batch(): BatchV4<{
|
|
70
74
|
text: GoogleModelId;
|
|
@@ -435,11 +439,13 @@ export function createGoogle(
|
|
|
435
439
|
provider.languageModel = createChatModel;
|
|
436
440
|
provider.chat = createChatModel;
|
|
437
441
|
provider.generativeAI = createChatModel;
|
|
438
|
-
provider.
|
|
439
|
-
new
|
|
442
|
+
provider.decisionModel = (modelId: GoogleModelId) =>
|
|
443
|
+
new DecisionLanguageModel({
|
|
440
444
|
model: createChatModel(modelId),
|
|
441
|
-
provider: `${providerName.replace(/\.generative-ai$/, '')}.
|
|
445
|
+
provider: `${providerName.replace(/\.generative-ai$/, '')}.decision`,
|
|
442
446
|
});
|
|
447
|
+
provider.evaluationModel =
|
|
448
|
+
provider.decisionModel as GoogleProvider['evaluationModel'];
|
|
443
449
|
provider.experimental_batch = createBatch;
|
|
444
450
|
provider.embedding = createEmbeddingModel;
|
|
445
451
|
provider.embeddingModel = createEmbeddingModel;
|
package/src/google-speech-api.ts
CHANGED
|
@@ -217,6 +217,7 @@ export class GoogleTranscriptionModel implements TranscriptionModelV4 {
|
|
|
217
217
|
language: undefined,
|
|
218
218
|
durationInSeconds: undefined,
|
|
219
219
|
warnings,
|
|
220
|
+
...(response.usage != null && { usage: response.usage }),
|
|
220
221
|
response: {
|
|
221
222
|
timestamp: currentDate,
|
|
222
223
|
modelId: this.modelId,
|
|
@@ -226,7 +227,7 @@ export class GoogleTranscriptionModel implements TranscriptionModelV4 {
|
|
|
226
227
|
...(response.usage != null
|
|
227
228
|
? {
|
|
228
229
|
providerMetadata: {
|
|
229
|
-
google: { usage: response.usage
|
|
230
|
+
google: { usage: response.usage },
|
|
230
231
|
},
|
|
231
232
|
}
|
|
232
233
|
: {}),
|
|
@@ -434,6 +435,7 @@ function createGoogleLiveTranscriptionStream({
|
|
|
434
435
|
segments: [],
|
|
435
436
|
language,
|
|
436
437
|
durationInSeconds: undefined,
|
|
438
|
+
usage: usageMetadata,
|
|
437
439
|
...(usageMetadata != null
|
|
438
440
|
? { providerMetadata: { google: { usageMetadata } } }
|
|
439
441
|
: {}),
|
|
@@ -710,5 +712,5 @@ const googleInteractionsTranscriptionResponseSchema = z.object({
|
|
|
710
712
|
}),
|
|
711
713
|
)
|
|
712
714
|
.nullish(),
|
|
713
|
-
usage: z.record(z.string(), z.
|
|
715
|
+
usage: z.record(z.string(), z.json()).nullish(),
|
|
714
716
|
});
|