XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 1
返回提交历史

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
OpenHands <openhands@all-hands.dev>
提交于

代码差异

2 个文件 +46 -16
Modified etc/unittest/test_gemini.py +21 -9
@@ -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")
Modified g4f/Provider/needs_auth/Gemini.py +25 -7
@@ -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