mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-15 23:31:29 +00:00
feat(gemini): add gemini-3.1-flash-lite-image (Nano Banana 2 Lite) pricing
Adds cost-map entries for gemini-3.1-flash-lite-image, gemini/... and vertex_ai/... variants using Google's published Nano Banana 2 Lite pricing ($0.25/1M input, $1.50/1M text output, $30/1M image output -> ~$0.0336 per 1K image). Mirrors the existing gemini-3.1-flash-image entry. Without this, completion_cost() raises "model isn't mapped yet" and Vertex generateContent pass-through cost tracking silently logs $0.
This commit is contained in:
parent
0c3017e1de
commit
586568f81c
3 changed files with 296 additions and 0 deletions
|
|
@ -17742,6 +17742,101 @@
|
|||
},
|
||||
"web_search_billing_unit": "per_query"
|
||||
},
|
||||
"gemini-3.1-flash-lite-image": {
|
||||
"input_cost_per_image": 0.00028,
|
||||
"input_cost_per_token": 2.5e-07,
|
||||
"litellm_provider": "vertex_ai-language-models",
|
||||
"max_input_tokens": 65536,
|
||||
"max_output_tokens": 32768,
|
||||
"max_tokens": 32768,
|
||||
"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",
|
||||
"supported_endpoints": [
|
||||
"/v1/chat/completions",
|
||||
"/v1/completions",
|
||||
"/v1/batch"
|
||||
],
|
||||
"supported_modalities": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"supported_output_modalities": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"supports_function_calling": false,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"gemini/gemini-3.1-flash-lite-image": {
|
||||
"rpm": 1000,
|
||||
"tpm": 4000000,
|
||||
"input_cost_per_image": 0.00028,
|
||||
"input_cost_per_token": 2.5e-07,
|
||||
"litellm_provider": "gemini",
|
||||
"max_input_tokens": 65536,
|
||||
"max_output_tokens": 32768,
|
||||
"max_tokens": 32768,
|
||||
"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",
|
||||
"supported_endpoints": [
|
||||
"/v1/chat/completions",
|
||||
"/v1/completions",
|
||||
"/v1/batch"
|
||||
],
|
||||
"supported_modalities": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"supported_output_modalities": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"supports_function_calling": false,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"vertex_ai/gemini-3.1-flash-lite-image": {
|
||||
"input_cost_per_image": 0.00028,
|
||||
"input_cost_per_token": 2.5e-07,
|
||||
"litellm_provider": "vertex_ai-language-models",
|
||||
"max_input_tokens": 65536,
|
||||
"max_output_tokens": 32768,
|
||||
"max_tokens": 32768,
|
||||
"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",
|
||||
"supported_endpoints": [
|
||||
"/v1/chat/completions",
|
||||
"/v1/completions",
|
||||
"/v1/batch"
|
||||
],
|
||||
"supported_modalities": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"supported_output_modalities": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"supports_function_calling": false,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"gemini-3.1-flash-image-preview": {
|
||||
"input_cost_per_image": 0.00056,
|
||||
"input_cost_per_token": 5e-07,
|
||||
|
|
|
|||
|
|
@ -17782,6 +17782,101 @@
|
|||
},
|
||||
"web_search_billing_unit": "per_query"
|
||||
},
|
||||
"gemini-3.1-flash-lite-image": {
|
||||
"input_cost_per_image": 0.00028,
|
||||
"input_cost_per_token": 2.5e-07,
|
||||
"litellm_provider": "vertex_ai-language-models",
|
||||
"max_input_tokens": 65536,
|
||||
"max_output_tokens": 32768,
|
||||
"max_tokens": 32768,
|
||||
"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",
|
||||
"supported_endpoints": [
|
||||
"/v1/chat/completions",
|
||||
"/v1/completions",
|
||||
"/v1/batch"
|
||||
],
|
||||
"supported_modalities": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"supported_output_modalities": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"supports_function_calling": false,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"gemini/gemini-3.1-flash-lite-image": {
|
||||
"rpm": 1000,
|
||||
"tpm": 4000000,
|
||||
"input_cost_per_image": 0.00028,
|
||||
"input_cost_per_token": 2.5e-07,
|
||||
"litellm_provider": "gemini",
|
||||
"max_input_tokens": 65536,
|
||||
"max_output_tokens": 32768,
|
||||
"max_tokens": 32768,
|
||||
"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",
|
||||
"supported_endpoints": [
|
||||
"/v1/chat/completions",
|
||||
"/v1/completions",
|
||||
"/v1/batch"
|
||||
],
|
||||
"supported_modalities": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"supported_output_modalities": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"supports_function_calling": false,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"vertex_ai/gemini-3.1-flash-lite-image": {
|
||||
"input_cost_per_image": 0.00028,
|
||||
"input_cost_per_token": 2.5e-07,
|
||||
"litellm_provider": "vertex_ai-language-models",
|
||||
"max_input_tokens": 65536,
|
||||
"max_output_tokens": 32768,
|
||||
"max_tokens": 32768,
|
||||
"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",
|
||||
"supported_endpoints": [
|
||||
"/v1/chat/completions",
|
||||
"/v1/completions",
|
||||
"/v1/batch"
|
||||
],
|
||||
"supported_modalities": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"supported_output_modalities": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"supports_function_calling": false,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"gemini-3.1-flash-image": {
|
||||
"input_cost_per_image": 0.00056,
|
||||
"input_cost_per_token": 5e-07,
|
||||
|
|
|
|||
106
tests/test_litellm/test_gemini_3_1_flash_lite_image_pricing.py
Normal file
106
tests/test_litellm/test_gemini_3_1_flash_lite_image_pricing.py
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
"""Pricing entry for ``gemini-3.1-flash-lite-image`` (Google's Nano Banana 2 Lite).
|
||||
|
||||
Google publishes: $0.25/1M input, $1.50/1M text output, and $30/1M image-output
|
||||
tokens for the Lite image model (https://cloud.google.com/vertex-ai/generative-ai/pricing).
|
||||
A 1K image is ~1120 output image tokens => ~$0.0336 / image.
|
||||
|
||||
Without this entry, ``completion_cost`` raises "model isn't mapped yet" and Vertex
|
||||
generateContent pass-through cost tracking silently logs $0. These tests pin the
|
||||
values in both the primary price map and the ``litellm/`` backup, and verify
|
||||
``get_model_info`` / ``completion_cost`` surface them.
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath("../..")) # Adds the parent directory to the system path
|
||||
|
||||
import litellm
|
||||
from litellm import completion_cost
|
||||
from litellm.types.utils import CompletionTokensDetailsWrapper, ModelResponse, Usage
|
||||
|
||||
VARIANTS = [
|
||||
"gemini-3.1-flash-lite-image",
|
||||
"gemini/gemini-3.1-flash-lite-image",
|
||||
"vertex_ai/gemini-3.1-flash-lite-image",
|
||||
]
|
||||
|
||||
EXPECTED = {
|
||||
"input_cost_per_token": 2.5e-07,
|
||||
"output_cost_per_token": 1.5e-06,
|
||||
"output_cost_per_image_token": 3e-05,
|
||||
"mode": "image_generation",
|
||||
}
|
||||
|
||||
|
||||
def _load_json(path: str) -> dict:
|
||||
with open(path, encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def _backup_path() -> str:
|
||||
return os.path.join(
|
||||
os.path.dirname(litellm.__file__),
|
||||
"model_prices_and_context_window_backup.json",
|
||||
)
|
||||
|
||||
|
||||
def _main_path() -> str:
|
||||
return os.path.join(
|
||||
os.path.dirname(__file__), "..", "..", "model_prices_and_context_window.json"
|
||||
)
|
||||
|
||||
|
||||
class TestGeminiFlashLiteImagePricingData:
|
||||
"""Both price maps must carry Google's published Nano Banana 2 Lite costs."""
|
||||
|
||||
def test_present_in_both_maps(self):
|
||||
main = _load_json(_main_path())
|
||||
backup = _load_json(_backup_path())
|
||||
for key in VARIANTS:
|
||||
for label, data in (("main", main), ("backup", backup)):
|
||||
assert key in data, f"{key} missing from {label} JSON"
|
||||
entry = data[key]
|
||||
for field, value in EXPECTED.items():
|
||||
assert entry[field] == value, f"{key} {field} in {label}: {entry.get(field)} != {value}"
|
||||
|
||||
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())
|
||||
entry = backup["gemini-3.1-flash-lite-image"]
|
||||
assert round(1120 * entry["output_cost_per_image_token"], 6) == entry["output_cost_per_image"]
|
||||
|
||||
|
||||
class TestGeminiFlashLiteImageModelInfo:
|
||||
"""``get_model_info`` and ``completion_cost`` must report the new costs."""
|
||||
|
||||
def test_get_model_info_and_cost(self):
|
||||
original = litellm.model_cost
|
||||
try:
|
||||
litellm.model_cost = _load_json(_backup_path())
|
||||
info = litellm.get_model_info("gemini-3.1-flash-lite-image")
|
||||
assert info["input_cost_per_token"] == EXPECTED["input_cost_per_token"]
|
||||
assert info["output_cost_per_token"] == EXPECTED["output_cost_per_token"]
|
||||
|
||||
# A 1K image => 1120 output image tokens => ~$0.0336 (billed at
|
||||
# output_cost_per_image_token, not the text output rate).
|
||||
resp = ModelResponse()
|
||||
resp.model = "gemini-3.1-flash-lite-image"
|
||||
resp.usage = Usage(
|
||||
prompt_tokens=7,
|
||||
completion_tokens=1120,
|
||||
total_tokens=1127,
|
||||
completion_tokens_details=CompletionTokensDetailsWrapper(
|
||||
image_tokens=1120, text_tokens=0
|
||||
),
|
||||
)
|
||||
cost = completion_cost(
|
||||
completion_response=resp,
|
||||
model="gemini-3.1-flash-lite-image",
|
||||
custom_llm_provider="vertex_ai",
|
||||
)
|
||||
# 1120 * 3e-5 (image) + 7 * 2.5e-7 (input) == 0.03360175
|
||||
assert abs(cost - 0.03360175) < 1e-6, f"unexpected cost {cost}"
|
||||
finally:
|
||||
litellm.model_cost = original
|
||||
Loading…
Add table
Reference in a new issue