@@ -10,6 +10,7 @@ const GEMINI_2_5_FLASH_PREFIX = "gemini-2.5-flash";
1010const GEMINI_3_1_PRO_PREFIX = "gemini-3.1-pro" ;
1111const GEMINI_3_1_FLASH_LITE_PREFIX = "gemini-3.1-flash-lite" ;
1212const GEMINI_3_1_FLASH_PREFIX = "gemini-3.1-flash" ;
13+ const GOOGLE_GEMINI_CLI_PROVIDER_ID = "google-gemini-cli" ;
1314const GEMINI_2_5_PRO_TEMPLATE_IDS = [ "gemini-2.5-pro" ] as const ;
1415const GEMINI_2_5_FLASH_LITE_TEMPLATE_IDS = [ "gemini-2.5-flash-lite" ] as const ;
1516const GEMINI_2_5_FLASH_TEMPLATE_IDS = [ "gemini-2.5-flash" ] as const ;
@@ -18,18 +19,26 @@ const GEMINI_3_1_FLASH_LITE_TEMPLATE_IDS = ["gemini-3.1-flash-lite-preview"] as
1819const GEMINI_3_1_FLASH_TEMPLATE_IDS = [ "gemini-3-flash-preview" ] as const ;
1920
2021type GoogleForwardCompatFamily = {
22+ googleTemplateIds : readonly string [ ] ;
23+ cliTemplateIds : readonly string [ ] ;
24+ preferExternalFirstForCli ?: boolean ;
25+ } ;
26+
27+ type GoogleTemplateSource = {
28+ templateProviderId : string ;
2129 templateIds : readonly string [ ] ;
2230} ;
2331
2432function cloneGoogleTemplateModel ( params : {
2533 providerId : string ;
2634 modelId : string ;
35+ templateProviderId : string ;
2736 templateIds : readonly string [ ] ;
2837 ctx : ProviderResolveDynamicModelContext ;
2938 patch ?: Partial < ProviderRuntimeModel > ;
3039} ) : ProviderRuntimeModel | undefined {
3140 return cloneFirstTemplateModel ( {
32- providerId : params . providerId ,
41+ providerId : params . templateProviderId ,
3342 modelId : params . modelId ,
3443 templateIds : params . templateIds ,
3544 ctx : params . ctx ,
@@ -40,36 +49,121 @@ function cloneGoogleTemplateModel(params: {
4049 } ) ;
4150}
4251
52+ function isGoogleGeminiCliProvider ( providerId : string ) : boolean {
53+ return providerId . trim ( ) . toLowerCase ( ) === GOOGLE_GEMINI_CLI_PROVIDER_ID ;
54+ }
55+
56+ function templateIdsForProvider (
57+ templateProviderId : string ,
58+ family : GoogleForwardCompatFamily ,
59+ ) : readonly string [ ] {
60+ return isGoogleGeminiCliProvider ( templateProviderId )
61+ ? family . cliTemplateIds
62+ : family . googleTemplateIds ;
63+ }
64+
65+ function buildGoogleTemplateSources ( params : {
66+ providerId : string ;
67+ templateProviderId ?: string ;
68+ family : GoogleForwardCompatFamily ;
69+ } ) : GoogleTemplateSource [ ] {
70+ const defaultTemplateProviderId = params . templateProviderId ?. trim ( )
71+ ? params . templateProviderId
72+ : isGoogleGeminiCliProvider ( params . providerId )
73+ ? "google"
74+ : GOOGLE_GEMINI_CLI_PROVIDER_ID ;
75+ const preferredExternalFirst =
76+ isGoogleGeminiCliProvider ( params . providerId ) &&
77+ params . family . preferExternalFirstForCli === true ;
78+ const orderedTemplateProviderIds = preferredExternalFirst
79+ ? [ defaultTemplateProviderId , params . providerId ]
80+ : [ params . providerId , defaultTemplateProviderId ] ;
81+
82+ const seen = new Set < string > ( ) ;
83+ const sources : GoogleTemplateSource [ ] = [ ] ;
84+ for ( const providerId of orderedTemplateProviderIds ) {
85+ const trimmed = providerId ?. trim ( ) ;
86+ if ( ! trimmed || seen . has ( trimmed ) ) {
87+ continue ;
88+ }
89+ seen . add ( trimmed ) ;
90+ sources . push ( {
91+ templateProviderId : trimmed ,
92+ templateIds : templateIdsForProvider ( trimmed , params . family ) ,
93+ } ) ;
94+ }
95+ return sources ;
96+ }
97+
4398export function resolveGoogleGeminiForwardCompatModel ( params : {
4499 providerId : string ;
100+ templateProviderId ?: string ;
45101 ctx : ProviderResolveDynamicModelContext ;
46102} ) : ProviderRuntimeModel | undefined {
47103 const trimmed = params . ctx . modelId . trim ( ) ;
48104 const lower = trimmed . toLowerCase ( ) ;
49105
50106 let family : GoogleForwardCompatFamily ;
107+ let patch : Partial < ProviderRuntimeModel > | undefined ;
51108 if ( lower . startsWith ( GEMINI_2_5_PRO_PREFIX ) ) {
52- family = { templateIds : GEMINI_2_5_PRO_TEMPLATE_IDS } ;
109+ family = {
110+ googleTemplateIds : GEMINI_2_5_PRO_TEMPLATE_IDS ,
111+ cliTemplateIds : GEMINI_3_1_PRO_TEMPLATE_IDS ,
112+ preferExternalFirstForCli : true ,
113+ } ;
53114 } else if ( lower . startsWith ( GEMINI_2_5_FLASH_LITE_PREFIX ) ) {
54- family = { templateIds : GEMINI_2_5_FLASH_LITE_TEMPLATE_IDS } ;
115+ family = {
116+ googleTemplateIds : GEMINI_2_5_FLASH_LITE_TEMPLATE_IDS ,
117+ cliTemplateIds : GEMINI_3_1_FLASH_LITE_TEMPLATE_IDS ,
118+ preferExternalFirstForCli : true ,
119+ } ;
55120 } else if ( lower . startsWith ( GEMINI_2_5_FLASH_PREFIX ) ) {
56- family = { templateIds : GEMINI_2_5_FLASH_TEMPLATE_IDS } ;
121+ family = {
122+ googleTemplateIds : GEMINI_2_5_FLASH_TEMPLATE_IDS ,
123+ cliTemplateIds : GEMINI_3_1_FLASH_TEMPLATE_IDS ,
124+ preferExternalFirstForCli : true ,
125+ } ;
57126 } else if ( lower . startsWith ( GEMINI_3_1_PRO_PREFIX ) ) {
58- family = { templateIds : GEMINI_3_1_PRO_TEMPLATE_IDS } ;
127+ family = {
128+ googleTemplateIds : GEMINI_3_1_PRO_TEMPLATE_IDS ,
129+ cliTemplateIds : GEMINI_3_1_PRO_TEMPLATE_IDS ,
130+ } ;
131+ if ( params . providerId === "google" || params . providerId === GOOGLE_GEMINI_CLI_PROVIDER_ID ) {
132+ patch = { reasoning : true } ;
133+ }
59134 } else if ( lower . startsWith ( GEMINI_3_1_FLASH_LITE_PREFIX ) ) {
60- family = { templateIds : GEMINI_3_1_FLASH_LITE_TEMPLATE_IDS } ;
135+ family = {
136+ googleTemplateIds : GEMINI_3_1_FLASH_LITE_TEMPLATE_IDS ,
137+ cliTemplateIds : GEMINI_3_1_FLASH_LITE_TEMPLATE_IDS ,
138+ } ;
61139 } else if ( lower . startsWith ( GEMINI_3_1_FLASH_PREFIX ) ) {
62- family = { templateIds : GEMINI_3_1_FLASH_TEMPLATE_IDS } ;
140+ family = {
141+ googleTemplateIds : GEMINI_3_1_FLASH_TEMPLATE_IDS ,
142+ cliTemplateIds : GEMINI_3_1_FLASH_TEMPLATE_IDS ,
143+ } ;
63144 } else {
64145 return undefined ;
65146 }
66147
67- return cloneGoogleTemplateModel ( {
148+ for ( const source of buildGoogleTemplateSources ( {
68149 providerId : params . providerId ,
69- modelId : trimmed ,
70- templateIds : family . templateIds ,
71- ctx : params . ctx ,
72- } ) ;
150+ templateProviderId : params . templateProviderId ,
151+ family,
152+ } ) ) {
153+ const model = cloneGoogleTemplateModel ( {
154+ providerId : params . providerId ,
155+ modelId : trimmed ,
156+ templateProviderId : source . templateProviderId ,
157+ templateIds : source . templateIds ,
158+ ctx : params . ctx ,
159+ patch,
160+ } ) ;
161+ if ( model ) {
162+ return model ;
163+ }
164+ }
165+
166+ return undefined ;
73167}
74168
75169export function isModernGoogleModel ( modelId : string ) : boolean {
0 commit comments