返回提交历史
Modified
etc/unittest/test_gemini.py
+21
-9
Modified
g4f/Provider/needs_auth/Gemini.py
+25
-7
XFEstudio/gpt4free
fix(gemini): fall back to known model for unknown Gemini names (#3508)
Unknown Gemini models such as gemini-3.8-flash raised ValueError in _resolve_model, which surfaced as a 500 from the API. Google releases new Gemini models faster than the hard-coded registry can track them, so route unrecognized names to the closest known model of the same family (pro/lite/flash) and log the fallback instead of rejecting the request. The @think= parsing and range validation still raise on genuinely invalid input. Updates the Gemini unit tests accordingly.
c896df0b
代码差异
2 个文件
+46
-16
@@ -181,15 +181,27 @@ class GeminiHelpersTest(unittest.TestCase):
181
181
resolved, _ = _resolve_model(legacy_name)
182
182
self.assertEqual(resolved, current_name)
183
183
184
def test_unknown_model_lists_supported_models(self):
185
with self.assertRaises(ValueError) as context:
186
_resolve_model("gemini-3.7-flash")
187
188
message = str(context.exception)
189
self.assertIn("Unknown Gemini model: gemini-3.7-flash", message)
190
self.assertIn("Supported models:", message)
191
self.assertIn("gemini-3.6-flash", message)
192
self.assertIn("gemini-3.5-flash-lite", message)
184
def test_unknown_model_falls_back_to_known_model(self):
185
# New Gemini models ship faster than the hard-coded registry can track
186
# them. Unknown names route to the closest known model of the same
187
# family instead of raising, so the provider no longer returns a 500.
188
self.assertEqual(_resolve_model("gemini-3.7-flash")[0], "gemini-3.6-flash")
189
self.assertEqual(_resolve_model("gemini-3.8-flash")[0], "gemini-3.6-flash")
190
self.assertEqual(_resolve_model("gemini-3.8-pro")[0], "gemini-3.1-pro")
191
self.assertEqual(
192
_resolve_model("gemini-3.9-flash-lite")[0], "gemini-3.5-flash-lite"
193
)
194
195
def test_unknown_thinking_model_enables_expanded_thinking(self):
196
model, expanded = _resolve_model("gemini-3.8-flash-thinking")
197
self.assertEqual(model, "gemini-3.6-flash")
198
self.assertTrue(expanded)
199
200
def test_invalid_thinking_mode_still_raises(self):
201
with self.assertRaises(ValueError):
202
_resolve_model("gemini-3.6-flash@think=abc")
203
with self.assertRaises(ValueError):
204
_resolve_model("gemini-3.6-flash@think=9")
193
205
194
206
def test_public_model_registry_exposes_current_models(self):
195
207
self.assertEqual(ModelRegistry.get("gemini-auto").name, "gemini-auto")
@@ -240,6 +240,18 @@ async def _iter_response_lines(
240
240
yield buffer.decode("utf-8", errors="replace")
241
241
242
242
243
def _fallback_model(requested_model: str) -> str:
244
# Google ships new Gemini models faster than the hard-coded registry can
245
# track them. Route an unknown name to the closest known model of the same
246
# family so the request keeps working until the registry is refreshed.
247
name = requested_model.lower()
248
if "pro" in name:
249
return "gemini-3.1-pro"
250
if "lite" in name:
251
return "gemini-3.5-flash-lite"
252
return "gemini-3.6-flash"
253
254
243
255
def _resolve_model(model: str, think_override: int = None) -> tuple[str, bool]:
244
256
requested_model = model
245
257
think_mode = think_override
@@ -255,14 +267,20 @@ def _resolve_model(model: str, think_override: int = None) -> tuple[str, bool]:
255
267
raise ValueError("Thinking mode must be an integer between 0 and 4")
256
268
model = MODEL_ALIASES.get(model, model)
257
269
if model not in models:
258
raise ValueError(
259
f"Unknown Gemini model: {model}. " f"Supported models: {', '.join(models)}"
270
fallback = _fallback_model(requested_model)
271
debug.log(
272
f"Unknown Gemini model: {model!r}. "
273
f"Falling back to {fallback!r}. "
274
f"Known models: {', '.join(models)}"
275
)
276
model = fallback
277
if think_mode is None:
278
expanded_thinking = (
279
requested_model in EXPANDED_MODEL_ALIASES
280
or "thinking" in requested_model.lower()
260
281
)
261
expanded_thinking = (
262
requested_model in EXPANDED_MODEL_ALIASES
263
if think_mode is None
264
else think_mode <= 2
265
)
282
else:
283
expanded_thinking = think_mode <= 2
266
284
return model, expanded_thinking
267
285
268
286