@ai-sdk/google
Advanced tools
+5
-5
| { | ||
| "name": "@ai-sdk/google", | ||
| "version": "4.0.2", | ||
| "version": "4.0.3", | ||
| "type": "module", | ||
@@ -38,4 +38,4 @@ "license": "Apache-2.0", | ||
| "dependencies": { | ||
| "@ai-sdk/provider": "4.0.0", | ||
| "@ai-sdk/provider-utils": "5.0.1" | ||
| "@ai-sdk/provider": "4.0.1", | ||
| "@ai-sdk/provider-utils": "5.0.2" | ||
| }, | ||
@@ -47,4 +47,4 @@ "devDependencies": { | ||
| "zod": "3.25.76", | ||
| "@vercel/ai-tsconfig": "0.0.0", | ||
| "@ai-sdk/test-server": "2.0.0" | ||
| "@ai-sdk/test-server": "2.0.0", | ||
| "@vercel/ai-tsconfig": "0.0.0" | ||
| }, | ||
@@ -51,0 +51,0 @@ "peerDependencies": { |
+119
-35
| import { | ||
| AISDKError, | ||
| type Experimental_VideoModelV4, | ||
| type Experimental_VideoModelV4File, | ||
| type SharedV4Warning, | ||
@@ -38,2 +39,99 @@ } from '@ai-sdk/provider'; | ||
| function getFirstFrameImage( | ||
| options: Parameters<Experimental_VideoModelV4['doGenerate']>[0], | ||
| ): Experimental_VideoModelV4File | undefined { | ||
| return options.frameImages?.find(frame => frame.frameType === 'first_frame') | ||
| ?.image; | ||
| } | ||
| function resolveStartImage( | ||
| options: Parameters<Experimental_VideoModelV4['doGenerate']>[0], | ||
| ): Experimental_VideoModelV4File | undefined { | ||
| return getFirstFrameImage(options) ?? options.image; | ||
| } | ||
| function getLastFrameImage( | ||
| options: Parameters<Experimental_VideoModelV4['doGenerate']>[0], | ||
| ): Experimental_VideoModelV4File | undefined { | ||
| return options.frameImages?.find(frame => frame.frameType === 'last_frame') | ||
| ?.image; | ||
| } | ||
| function getInputReferences( | ||
| options: Parameters<Experimental_VideoModelV4['doGenerate']>[0], | ||
| ): Array<Experimental_VideoModelV4File> | undefined { | ||
| if (options.frameImages != null && options.frameImages.length > 0) { | ||
| return undefined; | ||
| } | ||
| return options.inputReferences != null && options.inputReferences.length > 0 | ||
| ? options.inputReferences | ||
| : undefined; | ||
| } | ||
| function convertFileToGoogleImage( | ||
| file: Experimental_VideoModelV4File, | ||
| warnings: SharedV4Warning[], | ||
| ): Record<string, unknown> | undefined { | ||
| if (file.type === 'url') { | ||
| if (file.url.startsWith('gs://')) { | ||
| return { | ||
| gcsUri: file.url, | ||
| mimeType: 'image/png', | ||
| }; | ||
| } | ||
| warnings.push({ | ||
| type: 'unsupported', | ||
| feature: 'URL-based image input', | ||
| details: | ||
| 'Google Generative AI video models require base64-encoded images or GCS URIs. URL will be ignored.', | ||
| }); | ||
| return undefined; | ||
| } | ||
| const base64Data = | ||
| typeof file.data === 'string' | ||
| ? file.data | ||
| : convertUint8ArrayToBase64(file.data); | ||
| // The Gemini Developer API (generativelanguage.googleapis.com) requires | ||
| // inline image bytes wrapped as `inlineData`. | ||
| return { | ||
| inlineData: { | ||
| mimeType: file.mediaType || 'image/png', | ||
| data: base64Data, | ||
| }, | ||
| }; | ||
| } | ||
| function convertProviderReferenceImage( | ||
| refImg: NonNullable<GoogleVideoModelOptions['referenceImages']>[number], | ||
| ): Record<string, unknown> { | ||
| if (refImg.bytesBase64Encoded) { | ||
| return { | ||
| inlineData: { | ||
| mimeType: 'image/png', | ||
| data: refImg.bytesBase64Encoded, | ||
| }, | ||
| }; | ||
| } | ||
| if (refImg.gcsUri) { | ||
| return { | ||
| gcsUri: refImg.gcsUri, | ||
| }; | ||
| } | ||
| return refImg; | ||
| } | ||
| function convertInputReferenceImage( | ||
| file: Experimental_VideoModelV4File, | ||
| warnings: SharedV4Warning[], | ||
| ): Record<string, unknown> | undefined { | ||
| const image = convertFileToGoogleImage(file, warnings); | ||
| return image != null ? { image, referenceType: 'asset' } : undefined; | ||
| } | ||
| export class GoogleVideoModel implements Experimental_VideoModelV4 { | ||
@@ -75,42 +173,28 @@ readonly specificationVersion = 'v4'; | ||
| // Handle image-to-video: convert image to base64 | ||
| if (options.image != null) { | ||
| if (options.image.type === 'url') { | ||
| warnings.push({ | ||
| type: 'unsupported', | ||
| feature: 'URL-based image input', | ||
| details: | ||
| 'Google Generative AI video models require base64-encoded images. URL will be ignored.', | ||
| }); | ||
| } else { | ||
| const base64Data = | ||
| typeof options.image.data === 'string' | ||
| ? options.image.data | ||
| : convertUint8ArrayToBase64(options.image.data); | ||
| const startImage = resolveStartImage(options); | ||
| if (startImage != null) { | ||
| const image = convertFileToGoogleImage(startImage, warnings); | ||
| if (image != null) { | ||
| instance.image = image; | ||
| } | ||
| } | ||
| instance.image = { | ||
| inlineData: { | ||
| mimeType: options.image.mediaType || 'image/png', | ||
| data: base64Data, | ||
| }, | ||
| }; | ||
| const lastFrameImage = getLastFrameImage(options); | ||
| if (lastFrameImage != null) { | ||
| const lastFrame = convertFileToGoogleImage(lastFrameImage, warnings); | ||
| if (lastFrame != null) { | ||
| instance.lastFrame = lastFrame; | ||
| } | ||
| } | ||
| if (googleOptions?.referenceImages != null) { | ||
| instance.referenceImages = googleOptions.referenceImages.map(refImg => { | ||
| if (refImg.bytesBase64Encoded) { | ||
| return { | ||
| inlineData: { | ||
| mimeType: 'image/png', | ||
| data: refImg.bytesBase64Encoded, | ||
| }, | ||
| }; | ||
| } else if (refImg.gcsUri) { | ||
| return { | ||
| gcsUri: refImg.gcsUri, | ||
| }; | ||
| } | ||
| return refImg; | ||
| const inputReferences = getInputReferences(options); | ||
| if (inputReferences != null) { | ||
| instance.referenceImages = inputReferences.flatMap(reference => { | ||
| const converted = convertInputReferenceImage(reference, warnings); | ||
| return converted != null ? [converted] : []; | ||
| }); | ||
| } else if (googleOptions?.referenceImages != null) { | ||
| instance.referenceImages = googleOptions.referenceImages.map(refImg => | ||
| convertProviderReferenceImage(refImg), | ||
| ); | ||
| } | ||
@@ -117,0 +201,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
1636962
0.5%21824
0.57%+ Added
+ Added
- Removed
- Removed
Updated
Updated