refactor(model_info): restore provider-neutral Gemini chat baseline

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
kerry 2026-09-15 23:36:22 +00:00
parent 726430c0e7
commit 5b54bf2328
3 changed files with 19 additions and 15 deletions

View file

@ -58152,8 +58152,8 @@
},
{
"name": "gemini-chat-baseline",
"pattern": "^(?:gemini|vertex_ai)/gemini-(?!.*(?:-tts|-image|-live|-audio|-embedding|-computer-use|-robotics|-transcribe|-translate))(?:2\\.[5-9]|[3-9](?:\\.\\d{1,2})?)-(?:pro|flash)(?:-lite)?(?![a-z])",
"description": "A first-party Gemini text-chat id at 2.5 or higher, as gemini/<id> or vertex_ai/<id> (get_model_info tries the provider-prefixed name first, so a bare id under those providers matches too): gemini-<major>[.minor]-(pro|flash)[-lite] with any trailing preview, date or variant tag. Scoped to Google's own namespaces because resellers wrap the same models differently (one exposes them as mode responses without reasoning), so nothing below is certain there. The lookahead excludes the tts, image, live, audio, embedding, computer-use, robotics, transcribe and translate lines, which are different modes with different capabilities. 2.5 is the floor: every first-party text-chat Gemini from 2.5 onward in this map carries all of these fields, 1.5 and 2.0 do not and are fully mapped. Carries no token limits or pricing, so those stay on the standard unmapped behavior rather than a guessed number.",
"pattern": "gemini-(?!.*(?:-tts|-image|-live|-audio|-embedding|-computer-use|-robotics|-transcribe|-translate))(?:2[.-][5-9]|[3-9](?:[.-]\\d{1,2})?)-(?:pro|flash)(?:-lite)?(?![a-z])",
"description": "Any Gemini text-chat id at 2.5 or higher under any namespace, including bare ids, gemini/, vertex_ai/, openrouter/google/, deepinfra/google/, vercel_ai_gateway/google/, oci/google., and databricks-gemini-<major>-<minor>: gemini-<major>[.minor]-(pro|flash)[-lite] with any trailing preview, date or variant tag. The capability flags were verified against each of those providers' own catalogs and docs. The lookahead excludes the tts, image, live, audio, embedding, computer-use, robotics, transcribe and translate lines, which are different modes with different capabilities. Provider-specific deviations, such as Perplexity's Agent API serving these as mode responses, are carried by their exact map entries, which always win over this rule. Carries no token limits or pricing, so those stay on the standard unmapped behavior rather than a guessed number.",
"model_info": {
"mode": "chat",
"supports_reasoning": true,

View file

@ -58152,8 +58152,8 @@
},
{
"name": "gemini-chat-baseline",
"pattern": "^(?:gemini|vertex_ai)/gemini-(?!.*(?:-tts|-image|-live|-audio|-embedding|-computer-use|-robotics|-transcribe|-translate))(?:2\\.[5-9]|[3-9](?:\\.\\d{1,2})?)-(?:pro|flash)(?:-lite)?(?![a-z])",
"description": "A first-party Gemini text-chat id at 2.5 or higher, as gemini/<id> or vertex_ai/<id> (get_model_info tries the provider-prefixed name first, so a bare id under those providers matches too): gemini-<major>[.minor]-(pro|flash)[-lite] with any trailing preview, date or variant tag. Scoped to Google's own namespaces because resellers wrap the same models differently (one exposes them as mode responses without reasoning), so nothing below is certain there. The lookahead excludes the tts, image, live, audio, embedding, computer-use, robotics, transcribe and translate lines, which are different modes with different capabilities. 2.5 is the floor: every first-party text-chat Gemini from 2.5 onward in this map carries all of these fields, 1.5 and 2.0 do not and are fully mapped. Carries no token limits or pricing, so those stay on the standard unmapped behavior rather than a guessed number.",
"pattern": "gemini-(?!.*(?:-tts|-image|-live|-audio|-embedding|-computer-use|-robotics|-transcribe|-translate))(?:2[.-][5-9]|[3-9](?:[.-]\\d{1,2})?)-(?:pro|flash)(?:-lite)?(?![a-z])",
"description": "Any Gemini text-chat id at 2.5 or higher under any namespace, including bare ids, gemini/, vertex_ai/, openrouter/google/, deepinfra/google/, vercel_ai_gateway/google/, oci/google., and databricks-gemini-<major>-<minor>: gemini-<major>[.minor]-(pro|flash)[-lite] with any trailing preview, date or variant tag. The capability flags were verified against each of those providers' own catalogs and docs. The lookahead excludes the tts, image, live, audio, embedding, computer-use, robotics, transcribe and translate lines, which are different modes with different capabilities. Provider-specific deviations, such as Perplexity's Agent API serving these as mode responses, are carried by their exact map entries, which always win over this rule. Carries no token limits or pricing, so those stay on the standard unmapped behavior rather than a guessed number.",
"model_info": {
"mode": "chat",
"supports_reasoning": true,

View file

@ -457,12 +457,19 @@ def shipped_cost_map(monkeypatch):
("gemini-3.9-flash-lite-preview-09-2026", "vertex_ai"),
("vertex_ai/gemini-4-pro", None),
("gemini-4-pro-preview-customtools", "gemini"),
("google/gemini-4-pro", "openrouter"),
("google/gemini-4-pro", "deepinfra"),
("google/gemini-4-pro", "vercel_ai_gateway"),
("google.gemini-4-pro", "oci"),
("databricks-gemini-4-1-pro", "databricks"),
],
)
def test_shipped_gemini_chat_baseline_resolves_first_party_unmapped_ids(shipped_cost_map, model, provider):
def test_shipped_gemini_chat_baseline_resolves_unmapped_ids(shipped_cost_map, model, provider):
assert model not in litellm.model_cost
if provider == "gemini":
assert f"gemini/{model}" not in litellm.model_cost
elif provider in {"openrouter", "deepinfra", "vercel_ai_gateway", "oci", "databricks"}:
assert f"{provider}/{model}" not in litellm.model_cost
info = litellm.get_model_info(model, custom_llm_provider=provider)
assert info["litellm_provider"] == (provider or model.split("/")[0])
@ -481,16 +488,11 @@ def test_shipped_gemini_chat_baseline_resolves_first_party_unmapped_ids(shipped_
assert not info.get("output_cost_per_token")
def test_shipped_gemini_chat_baseline_skips_reseller_namespaces(shipped_cost_map):
for model, provider in (
("google/gemini-4-pro", "perplexity"),
("google/gemini-4-pro", "openrouter"),
("databricks-gemini-4-1-pro", "databricks"),
):
with pytest.raises(Exception, match="isn't mapped yet"):
litellm.get_model_info(model, custom_llm_provider=provider)
assert match_capability_generalizations("google/gemini-4-pro") is None
def test_shipped_gemini_chat_baseline_loses_to_perplexity_exact_entries(shipped_cost_map):
info = litellm.get_model_info("google/gemini-2.5-pro", custom_llm_provider="perplexity")
entry = litellm.model_cost["perplexity/google/gemini-2.5-pro"]
assert info["mode"] == "responses"
assert entry["supports_reasoning"] is False
def test_shipped_gemini_chat_baseline_skips_non_chat_and_pre_2_5_ids(shipped_cost_map):
@ -506,6 +508,8 @@ def test_shipped_gemini_chat_baseline_skips_non_chat_and_pre_2_5_ids(shipped_cos
"gemini/gemini-4-flashy",
"gemini/gemini-4-flash-transcribe",
"gemini/gemini-4-flash-live-translate-preview",
"databricks-gemini-3-1-flash-image",
"openrouter/google/gemini-2.0-flash-001",
):
assert match_capability_generalizations(model) is None, model