@@ -174,6 +174,38 @@ describe("GeminiHandler", () => {
174174 expect ( modelInfo . id ) . toBe ( geminiDefaultModelId ) // Default model
175175 } )
176176
177+ it ( "should honor a custom gemini model id not present in geminiModels (#227)" , ( ) => {
178+ const customHandler = new GeminiHandler ( {
179+ apiModelId : "gemini-3.5-flash" ,
180+ geminiApiKey : "test-key" ,
181+ } )
182+ const modelInfo = customHandler . getModel ( )
183+ // The configured id must be invoked, not silently swapped for the default.
184+ expect ( modelInfo . id ) . toBe ( "gemini-3.5-flash" )
185+ expect ( modelInfo . id ) . not . toBe ( geminiDefaultModelId )
186+ // A baseline ModelInfo is provided so downstream params resolve.
187+ expect ( modelInfo . info ) . toBeDefined ( )
188+ // Pricing is unknown for a custom model, so cost should not be reported
189+ // against the default model's rates.
190+ expect ( modelInfo . info . inputPrice ) . toBeUndefined ( )
191+ expect ( modelInfo . info . outputPrice ) . toBeUndefined ( )
192+ expect ( modelInfo . info . cacheReadsPrice ) . toBeUndefined ( )
193+ expect ( modelInfo . info . cacheWritesPrice ) . toBeUndefined ( )
194+ expect ( modelInfo . info . tiers ) . toBeUndefined ( )
195+ } )
196+
197+ it ( "should not treat Object prototype keys as known models" , ( ) => {
198+ // `"toString" in geminiModels` is true via the prototype chain, which would
199+ // otherwise resolve `info` to a function. An own-property check avoids this.
200+ const protoHandler = new GeminiHandler ( {
201+ apiModelId : "toString" ,
202+ geminiApiKey : "test-key" ,
203+ } )
204+ const modelInfo = protoHandler . getModel ( )
205+ expect ( modelInfo . id ) . toBe ( geminiDefaultModelId )
206+ expect ( modelInfo . info ) . toBeDefined ( )
207+ } )
208+
177209 it ( "should exclude apply_diff and include edit in tool preferences" , ( ) => {
178210 const modelInfo = handler . getModel ( )
179211 expect ( modelInfo . info . excludedTools ) . toContain ( "apply_diff" )
0 commit comments