@@ -39,6 +39,7 @@ import {
3939interface GenkitInfo {
4040 genkitVersion : string ;
4141 cliVersion : string ;
42+ genaiVersion : string ;
4243 vertexVersion : string ;
4344 googleAiVersion : string ;
4445 templateVersion : string ;
@@ -47,7 +48,8 @@ interface GenkitInfo {
4748
4849// This is the next breaking change version past the latest template.
4950const UNKNOWN_VERSION_TOO_HIGH = "2.0.0" ;
50- const MIN_VERSION = "0.6.0" ;
51+ const MIN_VERSION = "1.0.0-rc.1" ;
52+ const UNIFIED_PLUGIN_VERSION = "1.18.0" ; // also rename template if you change this
5153
5254// This is the latest template. It is the default.
5355const LATEST_TEMPLATE = "1.0.0" ;
@@ -92,6 +94,7 @@ async function getGenkitInfo(): Promise<GenkitInfo> {
9294
9395 const genkitVersion = await getPackageVersion ( "genkit" , "GENKIT_DEV_VERSION" ) ;
9496 const cliVersion = await getPackageVersion ( "genkit-cli" , "GENKIT_CLI_DEV_VERSION" ) ;
97+ const genaiVersion = await getPackageVersion ( "@genkit-ai/google-genai" , "GENKIT_GENAI_VERSION" ) ;
9598 const vertexVersion = await getPackageVersion ( "@genkit-ai/vertexai" , "GENKIT_VERTEX_VERSION" ) ;
9699 const googleAiVersion = await getPackageVersion ( "@genkit-ai/googleai" , "GENKIT_GOOGLEAI_VERSION" ) ;
97100
@@ -110,11 +113,14 @@ async function getGenkitInfo(): Promise<GenkitInfo> {
110113 if ( ! continueInstall ) {
111114 stopInstall = true ;
112115 }
113- } else if ( semver . gte ( genkitVersion , "1.0.0-rc.1" ) ) {
114- // 1.0.0-rc.1 < 1.0.0
115- templateVersion = "1.0.0" ;
116+ } else if (
117+ semver . gte ( genkitVersion , UNIFIED_PLUGIN_VERSION ) &&
118+ semver . gte ( genaiVersion , "0.0.2-rc.1" )
119+ ) {
120+ // Unified plugin template
121+ templateVersion = UNIFIED_PLUGIN_VERSION ;
116122 } else if ( semver . gte ( genkitVersion , MIN_VERSION ) ) {
117- templateVersion = "0.9 .0" ;
123+ templateVersion = "1.0 .0" ;
118124 } else {
119125 throw new FirebaseError (
120126 `The requested version of Genkit (${ genkitVersion } ) is no ` +
@@ -127,6 +133,7 @@ async function getGenkitInfo(): Promise<GenkitInfo> {
127133 cliVersion,
128134 vertexVersion,
129135 googleAiVersion,
136+ genaiVersion,
130137 templateVersion,
131138 stopInstall,
132139 } ;
@@ -241,55 +248,105 @@ export async function ensureVertexApiEnabled(options: Options): Promise<void> {
241248}
242249
243250interface PluginInfo {
251+ // The name of the plugin
252+ plugin : string ;
244253 // Imported items from `name` (can be comma list).
245254 imports : string ;
246255 // Comment for 'the model import line.
247256 modelImportComment ?: string ;
248257 // Initializer call.
249258 init : string ;
250- // Model name as an imported reference.
259+ // Model definition
251260 model ?: string ;
252- // Model name as a string reference.
253- modelStr ?: string ;
254261}
255262
256- interface PromptOption {
263+ interface ModelOption {
257264 // Label for prompt option.
258265 label : string ;
266+ // Provider (e.g. googleAI, vertexAI)
267+ provider ?: string ;
259268 // Plugin name.
260269 plugin ?: string ;
261270 // Package including version
262271 package ?: string ;
263272}
264273
265274/** Model to plugin name. */
266- function getModelOptions ( genkitInfo : GenkitInfo ) : Record < ModelProvider , PromptOption > {
267- const modelOptions : Record < ModelProvider , PromptOption > = {
268- vertexai : {
269- label : "Google Cloud Vertex AI" ,
270- plugin : "@genkit-ai/vertexai" ,
271- package : `@genkit-ai/vertexai@${ genkitInfo . vertexVersion } ` ,
272- } ,
273- googleai : {
274- label : "Google AI" ,
275- plugin : "@genkit-ai/googleai" ,
276- package : `@genkit-ai/googleai@${ genkitInfo . googleAiVersion } ` ,
277- } ,
278- none : { label : "None" , plugin : undefined , package : undefined } ,
279- } ;
275+ function getModelOptions ( genkitInfo : GenkitInfo ) : Record < ModelProvider , ModelOption > {
276+ let modelOptions : Record < ModelProvider , ModelOption > ;
277+ if ( semver . gte ( genkitInfo . templateVersion , UNIFIED_PLUGIN_VERSION ) ) {
278+ modelOptions = {
279+ vertexai : {
280+ label : "Google Cloud Vertex AI" ,
281+ provider : "vertexai" ,
282+ plugin : "@genkit-ai/google-genai" ,
283+ package : `@genkit-ai/google-genai@${ genkitInfo . genaiVersion } ` ,
284+ } ,
285+ googleai : {
286+ label : "Google AI" ,
287+ provider : "googleai" ,
288+ plugin : "@genkit-ai/google-genai" ,
289+ package : `@genkit-ai/google-genai@${ genkitInfo . genaiVersion } ` ,
290+ } ,
291+ none : { label : "None" } ,
292+ } ;
293+ } else {
294+ modelOptions = {
295+ vertexai : {
296+ label : "Google Cloud Vertex AI" ,
297+ plugin : "@genkit-ai/vertexai" ,
298+ package : `@genkit-ai/vertexai@${ genkitInfo . vertexVersion } ` ,
299+ } ,
300+ googleai : {
301+ label : "Google AI" ,
302+ plugin : "@genkit-ai/googleai" ,
303+ package : `@genkit-ai/googleai@${ genkitInfo . googleAiVersion } ` ,
304+ } ,
305+ none : { label : "None" } ,
306+ } ;
307+ }
308+
280309 return modelOptions ;
281310}
282311
283312/** Plugin name to descriptor. */
284313const pluginToInfo : Record < string , PluginInfo > = {
285314 "@genkit-ai/firebase" : {
315+ plugin : "@genkit-ai/firebase" ,
286316 imports : "firebase" ,
287317 init : `
288318 // Load the Firebase plugin, which provides integrations with several
289319 // Firebase services.
290320 firebase()` . trimStart ( ) ,
291321 } ,
322+ "@genkit-ai/google-genai(vertexai)" : {
323+ plugin : "@genkit-ai/google-genai" ,
324+ imports : "vertexAI" ,
325+ modelImportComment : `
326+ // Import vertexAI provider from the unified plugin. The Vertex AI API provides
327+ // access to many models.` ,
328+ init : ` // Load the VertexAI provider. You can optionally specify your location
329+ // and projectID by passing in a config object; if you don't, the provider
330+ // uses the value from environment variables like GCLOUD_PROJECT and GCLOUD_LOCATION.
331+ // If you want to use Vertex Express Mode, you can specify apiKey instead.
332+ vertexAI({location: "global"})` ,
333+ model : 'vertexAI.model("gemini-2.5-flash")' ,
334+ } ,
335+ "@genkit-ai/google-genai(googleai)" : {
336+ plugin : "@genkit-ai/google-genai" ,
337+ imports : "googleAI" ,
338+ modelImportComment : `
339+ // Import googleAI provider from the unified plugin. The Gemini Developer API
340+ // provides access to several generative models.` ,
341+ init : ` // Load the GoogleAI provider. You can optionally specify your API key by
342+ // passing in a config object; if you don't, the provider uses the value
343+ // from the GOOGLE_GENAI_API_KEY environment variable, which is the
344+ // recommended practice.
345+ googleAI()` ,
346+ model : 'googleAI.model("gemini-2.5-flash")' ,
347+ } ,
292348 "@genkit-ai/vertexai" : {
349+ plugin : "@genkit-ai/vertexai" ,
293350 imports : "vertexAI" ,
294351 modelImportComment : `
295352// Import models from the Vertex AI plugin. The Vertex AI API provides access to
@@ -299,9 +356,10 @@ const pluginToInfo: Record<string, PluginInfo> = {
299356 // by passing in a config object; if you don't, the Vertex AI plugin uses
300357 // the value from the GCLOUD_PROJECT environment variable.
301358 vertexAI({location: "us-central1"})` . trimStart ( ) ,
302- model : "gemini20Flash" ,
359+ model : 'vertexAI.model("gemini-2.5-flash")' ,
303360 } ,
304361 "@genkit-ai/googleai" : {
362+ plugin : "@genkit-ai/googleai" ,
305363 imports : "googleAI" ,
306364 modelImportComment : `
307365// Import models from the Google AI plugin. The Google AI API provides access to
@@ -312,10 +370,24 @@ const pluginToInfo: Record<string, PluginInfo> = {
312370 // the value from the GOOGLE_GENAI_API_KEY environment variable, which is
313371 // the recommended practice.
314372 googleAI()` . trimStart ( ) ,
315- model : "gemini20Flash" ,
373+ model : 'googleAI.model("gemini-2.5-flash")' ,
316374 } ,
317375} ;
318376
377+ function getPluginInfo ( option ?: ModelOption ) : PluginInfo {
378+ if ( option ?. provider && option . plugin ) {
379+ return pluginToInfo [ `${ option . plugin } (${ option . provider } )` ] ;
380+ }
381+ if ( option ?. plugin ) {
382+ return pluginToInfo [ option . plugin ] ;
383+ }
384+ return {
385+ plugin : "" ,
386+ imports : "" ,
387+ init : "" ,
388+ } ;
389+ }
390+
319391/** Basic packages required to use Genkit. */
320392function getBasePackages ( genkitVersion : string ) : string [ ] {
321393 const basePackages = [ "express" , `genkit@${ genkitVersion } ` ] ;
@@ -352,13 +424,8 @@ export async function genkitSetup(
352424 }
353425
354426 // Compile plugins list.
355- const plugins : string [ ] = [ ] ;
356427 const pluginPackages : string [ ] = [ ] ;
357428 pluginPackages . push ( `@genkit-ai/firebase@${ genkitInfo . genkitVersion } ` ) ;
358-
359- if ( modelOptions [ model ] ?. plugin ) {
360- plugins . push ( modelOptions [ model ] . plugin || "" ) ;
361- }
362429 if ( modelOptions [ model ] ?. package ) {
363430 pluginPackages . push ( modelOptions [ model ] . package || "" ) ;
364431 }
@@ -393,8 +460,7 @@ export async function genkitSetup(
393460 } ) ) ;
394461
395462 generateSampleFile (
396- modelOptions [ model ] . plugin ,
397- plugins ,
463+ modelOptions [ model ] ,
398464 projectDir ,
399465 genkitInfo . templateVersion ,
400466 enableTelemetry ,
@@ -515,25 +581,25 @@ async function installNpmPackages(
515581
516582/**
517583 * Generates a sample index.ts file.
518- * @param modelPlugin Model plugin name.
519- * @param configPlugins config plugins.
584+ * @param modelOption Information about the model/plugin
585+ * @param projectDir Where to put the sample
586+ * @param templateVersion Which template the use
587+ * @param enableTelemetry If telemetry is enabled or not.
520588 */
521589function generateSampleFile (
522- modelPlugin : string | undefined ,
523- configPlugins : string [ ] ,
590+ modelOption : ModelOption | undefined ,
524591 projectDir : string ,
525592 templateVersion : string ,
526593 enableTelemetry : boolean ,
527594) : void {
528595 let modelImport = "" ;
529- if ( modelPlugin && pluginToInfo [ modelPlugin ] . model ) {
530- const modelInfo = pluginToInfo [ modelPlugin ] . model || "" ;
531- modelImport = "\n" + generateImportStatement ( modelInfo , modelPlugin ) + "\n" ;
596+ const pluginInfo = getPluginInfo ( modelOption ) ;
597+ if ( pluginInfo . imports ) {
598+ modelImport = "\n" + generateImportStatement ( pluginInfo ) + "\n" ;
532599 }
533600 let modelImportComment = "" ;
534- if ( modelPlugin && pluginToInfo [ modelPlugin ] . modelImportComment ) {
535- const comment = pluginToInfo [ modelPlugin ] . modelImportComment || "" ;
536- modelImportComment = `\n${ comment } ` ;
601+ if ( pluginInfo . modelImportComment ) {
602+ modelImportComment = `\n${ pluginInfo . modelImportComment } ` ;
537603 }
538604 const commentedModelImport = `${ modelImportComment } ${ modelImport } ` ;
539605 const templatePath = path . join (
@@ -542,15 +608,10 @@ function generateSampleFile(
542608 ) ;
543609 const template = fs . readFileSync ( templatePath , "utf8" ) ;
544610 const sample = renderConfig (
545- configPlugins ,
611+ pluginInfo ,
546612 template
547613 . replace ( "$GENKIT_MODEL_IMPORT\n" , commentedModelImport )
548- . replace (
549- "$GENKIT_MODEL" ,
550- modelPlugin
551- ? pluginToInfo [ modelPlugin ] . model || pluginToInfo [ modelPlugin ] . modelStr || ""
552- : "'' /* TODO: Set a model. */" ,
553- ) ,
614+ . replace ( "$GENKIT_MODEL" , pluginInfo . model ?? "'' /* TODO: Set a model. */" ) ,
554615 enableTelemetry ,
555616 ) ;
556617 logLabeledBullet ( "genkit" , "Generating sample file" ) ;
@@ -640,21 +701,19 @@ async function updatePackageJson(nonInteractive: boolean, projectDir: string): P
640701 }
641702}
642703
643- function renderConfig ( pluginNames : string [ ] , template : string , enableTelemetry : boolean ) : string {
644- const imports = pluginNames
645- . map ( ( pluginName ) => generateImportStatement ( pluginToInfo [ pluginName ] . imports , pluginName ) )
646- . join ( "\n" ) ;
647- const plugins =
648- pluginNames . map ( ( pluginName ) => ` ${ pluginToInfo [ pluginName ] . init } ,` ) . join ( "\n" ) ||
649- " /* Add your plugins here. */" ;
704+ function renderConfig ( pluginInfo : PluginInfo , template : string , enableTelemetry : boolean ) : string {
705+ const plugins = pluginInfo . init || " /* Add your plugins here. */" ;
650706 return template
651- . replace ( "$GENKIT_CONFIG_IMPORTS" , imports )
707+ . replace ( "$GENKIT_CONFIG_IMPORTS" , generateImportStatement ( pluginInfo ) )
652708 . replace ( "$GENKIT_CONFIG_PLUGINS" , plugins )
653709 . replaceAll ( "$TELEMETRY_COMMENT" , enableTelemetry ? "" : "// " ) ;
654710}
655711
656- function generateImportStatement ( imports : string , name : string ) : string {
657- return `import {${ imports } } from "${ name } ";` ;
712+ function generateImportStatement ( pluginInfo : PluginInfo ) : string {
713+ if ( pluginInfo . imports && pluginInfo . plugin ) {
714+ return `import {${ pluginInfo . imports } } from "${ pluginInfo . plugin } ";` ;
715+ }
716+ return "" ;
658717}
659718
660719/**
0 commit comments