@@ -6,6 +6,40 @@ import { parseGoogleErrorMessage } from '../utils/googleErrorParser';
66import { imageUrlToBase64 } from '../utils/imageToBase64' ;
77import { parseDataUri } from '../utils/uriParser' ;
88
9+ // Maximum number of images allowed for processing
10+ const MAX_IMAGE_COUNT = 10 ;
11+
12+ /**
13+ * Process a single image URL and convert it to Google AI Part format
14+ */
15+ async function processImageForParts ( imageUrl : string ) : Promise < Part > {
16+ const { mimeType, base64, type } = parseDataUri ( imageUrl ) ;
17+
18+ if ( type === 'base64' ) {
19+ if ( ! base64 ) {
20+ throw new TypeError ( "Image URL doesn't contain base64 data" ) ;
21+ }
22+
23+ return {
24+ inlineData : {
25+ data : base64 ,
26+ mimeType : mimeType || 'image/png' ,
27+ } ,
28+ } ;
29+ } else if ( type === 'url' ) {
30+ const { base64 : urlBase64 , mimeType : urlMimeType } = await imageUrlToBase64 ( imageUrl ) ;
31+
32+ return {
33+ inlineData : {
34+ data : urlBase64 ,
35+ mimeType : urlMimeType ,
36+ } ,
37+ } ;
38+ } else {
39+ throw new TypeError ( `currently we don't support image url: ${ imageUrl } ` ) ;
40+ }
41+ }
42+
943/**
1044 * Extract image data from generateContent response
1145 */
@@ -71,36 +105,30 @@ async function generateImageByChatModel(
71105 const { model, params } = payload ;
72106 const actualModel = model . replace ( ':image' , '' ) ;
73107
108+ // Check for conflicting image parameters
109+ if ( params . imageUrl && params . imageUrls && params . imageUrls . length > 0 ) {
110+ throw new TypeError ( 'Cannot provide both imageUrl and imageUrls parameters simultaneously' ) ;
111+ }
112+
74113 // Build content parts
75114 const parts : Part [ ] = [ { text : params . prompt } ] ;
76115
77116 // Add image for editing if provided
78117 if ( params . imageUrl && params . imageUrl !== null ) {
79- const { mimeType, base64, type } = parseDataUri ( params . imageUrl ) ;
80-
81- if ( type === 'base64' ) {
82- if ( ! base64 ) {
83- throw new TypeError ( "Image URL doesn't contain base64 data" ) ;
84- }
85-
86- parts . push ( {
87- inlineData : {
88- data : base64 ,
89- mimeType : mimeType || 'image/png' ,
90- } ,
91- } ) ;
92- } else if ( type === 'url' ) {
93- const { base64 : urlBase64 , mimeType : urlMimeType } = await imageUrlToBase64 ( params . imageUrl ) ;
94-
95- parts . push ( {
96- inlineData : {
97- data : urlBase64 ,
98- mimeType : urlMimeType ,
99- } ,
100- } ) ;
101- } else {
102- throw new TypeError ( `currently we don't support image url: ${ params . imageUrl } ` ) ;
118+ const imagePart = await processImageForParts ( params . imageUrl ) ;
119+ parts . push ( imagePart ) ;
120+ }
121+
122+ // Add multiple images for editing if provided
123+ if ( params . imageUrls && Array . isArray ( params . imageUrls ) && params . imageUrls . length > 0 ) {
124+ if ( params . imageUrls . length > MAX_IMAGE_COUNT ) {
125+ throw new TypeError ( `Too many images provided. Maximum ${ MAX_IMAGE_COUNT } images allowed` ) ;
103126 }
127+
128+ const imageParts = await Promise . all (
129+ params . imageUrls . map ( ( imageUrl ) => processImageForParts ( imageUrl ) ) ,
130+ ) ;
131+ parts . push ( ...imageParts ) ;
104132 }
105133
106134 const contents : Content [ ] = [
0 commit comments