fix(gemini): align gemini-3.1-flash-lite-image capabilities with model cards

Output limit is 4096, structured outputs unsupported, and caching/function calling differ per route. Adds AI Studio batch rates.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
mateo 2026-08-06 19:21:20 +00:00
parent 586568f81c
commit c8941f671f
3 changed files with 80 additions and 24 deletions

View file

@ -17747,8 +17747,8 @@
"input_cost_per_token": 2.5e-07,
"litellm_provider": "vertex_ai-language-models",
"max_input_tokens": 65536,
"max_output_tokens": 32768,
"max_tokens": 32768,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "image_generation",
"output_cost_per_image": 0.0336,
"output_cost_per_image_token": 3e-05,
@ -17769,7 +17769,8 @@
],
"supports_function_calling": false,
"supports_prompt_caching": true,
"supports_response_schema": true,
"supports_response_schema": false,
"supports_reasoning": true,
"supports_system_messages": true,
"supports_vision": true
},
@ -17778,15 +17779,17 @@
"tpm": 4000000,
"input_cost_per_image": 0.00028,
"input_cost_per_token": 2.5e-07,
"input_cost_per_token_batches": 1.25e-07,
"litellm_provider": "gemini",
"max_input_tokens": 65536,
"max_output_tokens": 32768,
"max_tokens": 32768,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "image_generation",
"output_cost_per_image": 0.0336,
"output_cost_per_image_token": 3e-05,
"output_cost_per_token": 1.5e-06,
"source": "https://cloud.google.com/vertex-ai/generative-ai/pricing#gemini-models",
"output_cost_per_token_batches": 7.5e-07,
"source": "https://ai.google.dev/gemini-api/docs/pricing#gemini-3.1-flash-lite-image",
"supported_endpoints": [
"/v1/chat/completions",
"/v1/completions",
@ -17800,9 +17803,10 @@
"text",
"image"
],
"supports_function_calling": false,
"supports_prompt_caching": true,
"supports_response_schema": true,
"supports_function_calling": true,
"supports_prompt_caching": false,
"supports_response_schema": false,
"supports_reasoning": true,
"supports_system_messages": true,
"supports_vision": true
},
@ -17811,8 +17815,8 @@
"input_cost_per_token": 2.5e-07,
"litellm_provider": "vertex_ai-language-models",
"max_input_tokens": 65536,
"max_output_tokens": 32768,
"max_tokens": 32768,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "image_generation",
"output_cost_per_image": 0.0336,
"output_cost_per_image_token": 3e-05,
@ -17833,7 +17837,8 @@
],
"supports_function_calling": false,
"supports_prompt_caching": true,
"supports_response_schema": true,
"supports_response_schema": false,
"supports_reasoning": true,
"supports_system_messages": true,
"supports_vision": true
},

View file

@ -17787,8 +17787,8 @@
"input_cost_per_token": 2.5e-07,
"litellm_provider": "vertex_ai-language-models",
"max_input_tokens": 65536,
"max_output_tokens": 32768,
"max_tokens": 32768,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "image_generation",
"output_cost_per_image": 0.0336,
"output_cost_per_image_token": 3e-05,
@ -17809,7 +17809,8 @@
],
"supports_function_calling": false,
"supports_prompt_caching": true,
"supports_response_schema": true,
"supports_response_schema": false,
"supports_reasoning": true,
"supports_system_messages": true,
"supports_vision": true
},
@ -17818,15 +17819,17 @@
"tpm": 4000000,
"input_cost_per_image": 0.00028,
"input_cost_per_token": 2.5e-07,
"input_cost_per_token_batches": 1.25e-07,
"litellm_provider": "gemini",
"max_input_tokens": 65536,
"max_output_tokens": 32768,
"max_tokens": 32768,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "image_generation",
"output_cost_per_image": 0.0336,
"output_cost_per_image_token": 3e-05,
"output_cost_per_token": 1.5e-06,
"source": "https://cloud.google.com/vertex-ai/generative-ai/pricing#gemini-models",
"output_cost_per_token_batches": 7.5e-07,
"source": "https://ai.google.dev/gemini-api/docs/pricing#gemini-3.1-flash-lite-image",
"supported_endpoints": [
"/v1/chat/completions",
"/v1/completions",
@ -17840,9 +17843,10 @@
"text",
"image"
],
"supports_function_calling": false,
"supports_prompt_caching": true,
"supports_response_schema": true,
"supports_function_calling": true,
"supports_prompt_caching": false,
"supports_response_schema": false,
"supports_reasoning": true,
"supports_system_messages": true,
"supports_vision": true
},
@ -17851,8 +17855,8 @@
"input_cost_per_token": 2.5e-07,
"litellm_provider": "vertex_ai-language-models",
"max_input_tokens": 65536,
"max_output_tokens": 32768,
"max_tokens": 32768,
"max_output_tokens": 4096,
"max_tokens": 4096,
"mode": "image_generation",
"output_cost_per_image": 0.0336,
"output_cost_per_image_token": 3e-05,
@ -17873,7 +17877,8 @@
],
"supports_function_calling": false,
"supports_prompt_caching": true,
"supports_response_schema": true,
"supports_response_schema": false,
"supports_reasoning": true,
"supports_system_messages": true,
"supports_vision": true
},

View file

@ -33,6 +33,30 @@ EXPECTED = {
"mode": "image_generation",
}
EXPECTED_CAPABILITIES = {
"max_output_tokens": 4096,
"max_tokens": 4096,
"supports_response_schema": False,
"supports_reasoning": True,
}
EXPECTED_PER_ROUTE = {
"gemini-3.1-flash-lite-image": {
"supports_prompt_caching": True,
"supports_function_calling": False,
},
"vertex_ai/gemini-3.1-flash-lite-image": {
"supports_prompt_caching": True,
"supports_function_calling": False,
},
"gemini/gemini-3.1-flash-lite-image": {
"supports_prompt_caching": False,
"supports_function_calling": True,
"input_cost_per_token_batches": 1.25e-07,
"output_cost_per_token_batches": 7.5e-07,
},
}
def _load_json(path: str) -> dict:
with open(path, encoding="utf-8") as f:
@ -65,6 +89,28 @@ class TestGeminiFlashLiteImagePricingData:
for field, value in EXPECTED.items():
assert entry[field] == value, f"{key} {field} in {label}: {entry.get(field)} != {value}"
def test_capabilities_match_model_cards(self):
main = _load_json(_main_path())
backup = _load_json(_backup_path())
for key in VARIANTS:
expected = {**EXPECTED_CAPABILITIES, **EXPECTED_PER_ROUTE[key]}
for label, data in (("main", main), ("backup", backup)):
entry = data[key]
for field, value in expected.items():
assert entry[field] == value, f"{key} {field} in {label}: {entry.get(field)} != {value}"
def test_grounding_fields_absent(self):
"""Grounding with Google Search is unsupported on Lite, so no search pricing."""
for path in (_main_path(), _backup_path()):
data = _load_json(path)
for key in VARIANTS:
for field in (
"supports_web_search",
"search_context_cost_per_query",
"web_search_billing_unit",
):
assert field not in data[key], f"{key} should not define {field}"
def test_image_output_pricing_consistent(self):
"""1120 image-output tokens * output_cost_per_image_token == output_cost_per_image."""
backup = _load_json(_backup_path())