Skip to content

Commit f3c2e88

Browse files
gr2mvercel-ai-sdk[bot]
authored andcommitted
Backport conflicts for PR #10462 to release-v5.0
1 parent ebfa423 commit f3c2e88

File tree

8 files changed

+81
-20
lines changed

8 files changed

+81
-20
lines changed

.changeset/popular-hounds-boil.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@ai-sdk/provider': patch
3+
'@ai-sdk/google': patch
4+
'ai': patch
5+
---
6+
7+
fix(google): add thought signature to gemini 3 pro image parts
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { google } from '@ai-sdk/google';
2+
import { generateText } from 'ai';
3+
4+
import { presentImages } from '../lib/present-image';
5+
import { run } from '../lib/run';
6+
7+
import 'dotenv/config';
8+
9+
run(async () => {
10+
const step1 = await generateText({
11+
model: google('gemini-3-pro-image-preview'),
12+
prompt:
13+
'Create an image of Los Angeles where all car infrastructure has been replaced with bike infrastructure, trains, pedestrian zones, and parks. The image should be photorealistic and vibrant.',
14+
});
15+
16+
await presentImages(step1.files);
17+
18+
const step2 = await generateText({
19+
model: google('gemini-3-pro-image-preview'),
20+
messages: [
21+
...step1.response.messages,
22+
{
23+
role: 'user',
24+
content:
25+
'Now create a variation of the image, but in the style of a watercolor painting.',
26+
},
27+
],
28+
});
29+
30+
await presentImages(step2.files);
31+
});

packages/ai/src/generate-text/generate-text.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,9 @@ function asContent<TOOLS extends ToolSet>({
884884
return {
885885
type: 'file' as const,
886886
file: new DefaultGeneratedFile(part),
887+
...(part.providerMetadata != null
888+
? { providerMetadata: part.providerMetadata }
889+
: {}),
887890
};
888891
}
889892

packages/google/src/convert-to-google-generative-ai-messages.test.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -323,19 +323,6 @@ describe('assistant messages', () => {
323323
});
324324
});
325325

326-
it('should throw error for non-PNG images in assistant messages', async () => {
327-
expect(() =>
328-
convertToGoogleGenerativeAIMessages([
329-
{
330-
role: 'assistant',
331-
content: [
332-
{ type: 'file', data: 'AAECAw==', mediaType: 'image/jpeg' },
333-
],
334-
},
335-
]),
336-
).toThrow('Only PNG images are supported in assistant messages');
337-
});
338-
339326
it('should throw error for URL file data in assistant messages', async () => {
340327
expect(() =>
341328
convertToGoogleGenerativeAIMessages([

packages/google/src/convert-to-google-generative-ai-messages.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,6 @@ export function convertToGoogleGenerativeAIMessages(
107107
}
108108

109109
case 'file': {
110-
if (part.mediaType !== 'image/png') {
111-
throw new UnsupportedFunctionalityError({
112-
functionality:
113-
'Only PNG images are supported in assistant messages',
114-
});
115-
}
116-
117110
if (part.data instanceof URL) {
118111
throw new UnsupportedFunctionalityError({
119112
functionality:
@@ -126,6 +119,7 @@ export function convertToGoogleGenerativeAIMessages(
126119
mimeType: part.mediaType,
127120
data: convertToBase64(part.data),
128121
},
122+
thoughtSignature,
129123
};
130124
}
131125

packages/google/src/google-generative-ai-language-model.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,6 +1410,7 @@ describe('doGenerate', () => {
14101410
{
14111411
"data": "base64encodedimagedata",
14121412
"mediaType": "image/jpeg",
1413+
"providerMetadata": undefined,
14131414
"type": "file",
14141415
},
14151416
{
@@ -1420,6 +1421,7 @@ describe('doGenerate', () => {
14201421
{
14211422
"data": "anotherbase64encodedimagedata",
14221423
"mediaType": "image/png",
1424+
"providerMetadata": undefined,
14231425
"type": "file",
14241426
},
14251427
]
@@ -1472,11 +1474,13 @@ describe('doGenerate', () => {
14721474
{
14731475
"data": "imagedata1",
14741476
"mediaType": "image/jpeg",
1477+
"providerMetadata": undefined,
14751478
"type": "file",
14761479
},
14771480
{
14781481
"data": "imagedata2",
14791482
"mediaType": "image/png",
1483+
"providerMetadata": undefined,
14801484
"type": "file",
14811485
},
14821486
]
@@ -1591,11 +1595,13 @@ describe('doGenerate', () => {
15911595
{
15921596
"data": "validimagedata",
15931597
"mediaType": "image/jpeg",
1598+
"providerMetadata": undefined,
15941599
"type": "file",
15951600
},
15961601
{
15971602
"data": "pdfdata",
15981603
"mediaType": "application/pdf",
1604+
"providerMetadata": undefined,
15991605
"type": "file",
16001606
},
16011607
]

packages/google/src/google-generative-ai-language-model.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,9 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV2 {
271271
type: 'file' as const,
272272
data: part.inlineData.data,
273273
mediaType: part.inlineData.mimeType,
274+
providerMetadata: part.thoughtSignature
275+
? { google: { thoughtSignature: part.thoughtSignature } }
276+
: undefined,
274277
});
275278
}
276279
}
@@ -809,6 +812,7 @@ const getContentSchema = () =>
809812
mimeType: z.string(),
810813
data: z.string(),
811814
}),
815+
thoughtSignature: z.string().nullish(),
812816
}),
813817
z.object({
814818
executableCode: z
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { SharedV3ProviderMetadata } from '../../shared';
2+
3+
/**
4+
A file that has been generated by the model.
5+
Generated files as base64 encoded strings or binary data.
6+
The files should be returned without any unnecessary conversion.
7+
*/
8+
export type LanguageModelV3File = {
9+
type: 'file';
10+
11+
/**
12+
The IANA media type of the file, e.g. `image/png` or `audio/mp3`.
13+
14+
@see https://www.iana.org/assignments/media-types/media-types.xhtml
15+
*/
16+
mediaType: string;
17+
18+
/**
19+
Generated file data as base64 encoded strings or binary data.
20+
21+
The file data should be returned without any unnecessary conversion.
22+
If the API returns base64 encoded strings, the file data should be returned
23+
as base64 encoded strings. If the API returns binary data, the file data should
24+
be returned as binary data.
25+
*/
26+
data: string | Uint8Array;
27+
28+
providerMetadata?: SharedV3ProviderMetadata;
29+
};

0 commit comments

Comments
 (0)