Skip to content

gemini image models fixes in /images/generations and /images/edits: usage logging, spend calculation, passing size params - #28275

Closed
DmitriyAlergant wants to merge 12 commits into
BerriAI:litellm_oss_stagingfrom
DmitriyAlergant:codex/gemini-image-usage-routing
Closed

gemini image models fixes in /images/generations and /images/edits: usage logging, spend calculation, passing size params#28275
DmitriyAlergant wants to merge 12 commits into
BerriAI:litellm_oss_stagingfrom
DmitriyAlergant:codex/gemini-image-usage-routing

Conversation

@DmitriyAlergant

@DmitriyAlergant DmitriyAlergant commented May 19, 2026

Copy link
Copy Markdown
Contributor

Relevant issues

  1. Fixes [Bug]: Cannot generate 2K images with Gemini 3.1 Flash Image Preview (stuck at 1K) - extra_body is stripped #24621

  2. Fixes incorrect usage and spend logging for /images/generations and /images/edits when using Gemini Nano Banana models: image_tokens were not captured; Previously /images/edits incorrectly applied "cost per image" calculation (wrong for nano banana), /images/generations simply ignored the cost of image generation and only billed for input tokens.

  3. imagen model (gemini/imagen-4.0-generate-001) did not work via /images/generations due to misapplied branch condition looking for "gemini" in model name (bug accidentally discovered during testing, quick fix).

Prior PRs were incomplete:

@Chesars FYI

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have Added testing in the tests/test_litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • [...] My PR's scope is as isolated as possible, it only solves 1 specific problem
    • multiple issues but they are all related and in the same module: not feasible to submit separate PRs as they would conflict with each other
  • I am requesting Greptile review by commenting @greptileai and will receiv a Confidence Score of at least 4/5 before requesting a maintainer review

Proof of Fix

Gemini /v1/images/generations — OpenAI size

curl -sS -X POST "http://localhost:4000/v1/images/generations" \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gemini-3.1-flash-image-preview","prompt":"A simple icon centered on a white background","n":1,"size":"768x1376"}'
# PASS: got 768x1376 for requested 9:16, 1K
# PASS: spend log usage included generated image tokens, spend calculated correctly

Gemini /v1/images/generations — native imageConfig

curl -sS -X POST "http://localhost:4000/v1/images/generations" \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gemini-3.1-flash-image-preview","prompt":"A wide simple icon centered on a white background","imageConfig":{"aspectRatio":"16:9","imageSize":"2K"}}'
# PASS: got 2752x1536 for requested 16:9, 2K
# PASS: spend log usage included generated image tokens, spend calculated correctly

Imagen /v1/images/generations

curl -sS -X POST "http://localhost:4000/v1/images/generations" \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"imagen-4.0-generate-001","prompt":"A simple blue circle icon centered on a white background","n":1,"size":"1024x1024"}'
# PASS: returned 1 base64 image from Imagen `predictions[0].bytesBase64Encoded` response path
# PASS: spend log usage included generated 1 image, spend calculated correctly based on 1x output_cost_per_image

Gemini /v1/images/edits — multipart image upload + imageConfig

curl -sS -X POST "http://localhost:4000/v1/images/edits" \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -F "model=gemini-3.1-flash-image-preview" \
  -F "prompt=Edit the uploaded image: keep the main subject recognizable and add a thick blue border around the outside. Do not create an unrelated scene." \
  -F "image=@/tmp/gemini-edit-input.png;type=image/png" \
  -F 'imageConfig={"aspectRatio":"16:9","imageSize":"1K"}'
# PASS: got 1376x768 for requested 16:9, 1K
# PASS: spend log usage included prompt image tokens and generated image tokens, spend calculated correctly

Spend log rows:

Case Request ID Result Spend validation
Gemini size d05f2512-7251-4d9c-8c68-1fa140605471 768x1376 82.5e-7 + 3021.5e-6 + 1120*6e-5 = 0.067655, logged 0.06765499999999999
Gemini imageConfig a64b373c-9159-4339-a7b4-3e3d4d2ac8a5 2752x1536 92.5e-7 + 3531.5e-6 + 1680*6e-5 = 0.10133175, logged 0.10133175
Imagen e28b976d-4d57-40c3-b8b1-3029f7abbd69 1024x1024, 1 image flat output_cost_per_image = 0.04, logged 0.04
Gemini edit 21a25516-e6b9-4684-bf05-91f54c0185e7 1376x768 2852.5e-7 + 2081.5e-6 + 1120*6e-5 = 0.06758325, logged 0.06758325

Screenshot

CleanShot 2026-05-19 at 17 44 26@2x

Type

🐛 Bug Fix

Changes

For Gemini /v1/images/generations and /v1/images/edits endpoints:

  • Respect OpenAI-style size for Gemini image generation by mapping it to Gemini generationConfig.imageConfig. Use the documented Gemini image aspect ratio and resolution table for exact matches, then snap unsupported dimensions to the closest known aspect ratio/resolution.
  • Allow and preserve explicit Gemini-style camelCase imageConfig as-is, if provided in the body
  • Omit imageConfig entirely for size=auto or unparseable sizes so Gemini defaults remain in control.
  • For Gemini 2.5 Flash image models, forward only aspectRatio and omit imageSize.
  • Use Gemini-reported Candidate Token Counts to populate completion token details including image_tokens for correct usage logging and spend calculation for both endpoints
  • DRY refactoring reduced code duplication between Gemini /images/generations and /images/edits endpoints

@codecov

codecov Bot commented May 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.69663% with 13 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
litellm/llms/gemini/common_utils.py 88.76% 10 Missing ⚠️
litellm/litellm_core_utils/llm_cost_calc/utils.py 92.85% 2 Missing ⚠️
...llm/llms/gemini/image_generation/transformation.py 91.66% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@greptile-apps

greptile-apps Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes usage logging, spend calculation, and parameter handling for Gemini image models on the /images/generations and /images/edits endpoints. The changes include a comprehensive OpenAI-to-Gemini size-mapping table, explicit imageConfig passthrough (with JSON-string parsing for multipart form uploads), correct image/text token-breakdown tracking via usageMetadata, and a bug fix for Imagen models being routed to the wrong endpoint.

  • Size mapping overhaul: replaces the tiny 5-entry aspect_ratio_map with a full lookup table sourced from Google's documentation (14 aspect ratios × 4 resolutions = ~70 exact entries), plus closest-ratio snapping for unsupported dimensions using logarithmic distance.
  • Usage token tracking: extracts candidatesTokensDetails to split output tokens into image vs. text buckets; calculate_image_response_cost_from_usage is updated to respect those details instead of blindly treating every completion token as an image token.
  • DRY refactoring: shared map_openai_image_params_to_gemini, get_gemini_image_generation_config, and transform_gemini_image_usage helpers eliminate parallel implementations between the generation and edit pathways.

Confidence Score: 5/5

Safe to merge — all changes are additive fixes confined to Gemini image model paths with no impact on other providers.

The bug fixes are narrow and well-scoped: a wrong endpoint condition for Imagen, missing token-breakdown fields in spend calculation, and missing size-to-config mapping. All three fixes are verified by the PR's own proof-of-spend table and by the new parametrised unit tests that cover every documented Gemini size combination. The shared helpers extracted by the refactor are straightforward and don't alter any existing public contracts.

No files require special attention.

Important Files Changed

Filename Overview
litellm/llms/gemini/common_utils.py Adds the size-mapping lookup table, shared param-mapping helpers, and get_gemini_image_generation_config; logic is correct and well-tested.
litellm/llms/gemini/image_usage_transformation.py New shared utility that transforms Gemini usageMetadata into ImageUsage; correctly handles present/absent candidatesTokensDetails and reconciles any token-count gap into text tokens.
litellm/llms/gemini/image_generation/transformation.py Replaces bespoke param-mapping and usage-transform code with shared helpers; fixes the 'gemini' in model endpoint condition with is_gemini_image_model() to correctly route Imagen models.
litellm/llms/gemini/image_edit/transformation.py Now supports n and imageConfig params, delegates to shared helpers, and populates model_response.usage from usageMetadata for correct spend calculation.
litellm/llms/gemini/image_edit/cost_calculator.py Delegates entirely to the image-generation cost calculator; eliminates the now-incorrect flat per-image calculation.
litellm/litellm_core_utils/llm_cost_calc/utils.py Updated to read completion_tokens_details/output_tokens_details from usage when present instead of always treating all completion tokens as image tokens.
litellm/utils.py Adds imageConfig as a recognised optional param for image generation so it flows through the standard param-extraction pipeline.
tests/test_litellm/llms/gemini/test_gemini_image_generation_transformation.py New test file; covers size mapping, imageConfig precedence, Imagen vs. Gemini routing, usage token details, and fallback behaviour. All mocked, no real network calls.
tests/test_litellm/llms/gemini/test_cost_calculator.py Adds cost-calculator tests that verify token-based pricing, output-token-detail splits, and flat-image fallback; uses LITELLM_LOCAL_MODEL_COST_MAP to avoid network calls.
tests/llm_translation/test_gemini.py Adds exhaustive parametrised tests for all 56+ documented size/ratio/imageSize combinations plus snap-to-nearest and passthrough cases. All use mocked HTTP.
litellm/types/images/main.py Adds imageConfig to ImageEditOptionalRequestParams so the new param is recognised in the type system.
litellm/types/llms/gemini.py Adds imageSize field to GeminiImageGenerationParameters to match the new param the API now accepts.
litellm/types/llms/openai.py Adds imageConfig to OpenAIImageGenerationOptionalParams literal union.
tests/test_litellm/llms/gemini/image_edit/test_gemini_image_edit_transformation.py Extended with tests for n, imageConfig passthrough, JSON-string parsing, imageSize stripping for 2.5-flash, and usage metadata extraction.
tests/proxy_unit_tests/test_proxy_server.py Minor addition: imageConfig added to the test_img_gen mock fixture to confirm the param flows through the proxy layer.

Reviews (3): Last reviewed commit: "Clarify Gemini candidate count precedenc..." | Re-trigger Greptile

Comment thread litellm/llms/gemini/common_utils.py
Comment thread litellm/llms/gemini/common_utils.py Outdated
@oss-pr-review-agent-shin

Copy link
Copy Markdown
Contributor

🤖 litellm-agent: This PR is currently BLOCKED from merge.

Score: 3/5

Why blocked:

  • 1 PR-related CI failure (This PR will be auto-closed as it lacks a screenshot for proof of fix. Please include one in the PR description. Add the screenshot-exempt label if this PR has no visible output (e.g. pure docs, CI config).) (pr_related_failures, -2 pts)

Details: Score docked for: 1 PR-related CI failure (This PR will be auto-closed as it lacks a screenshot for proof of fix. Please include one in the PR description. Add the screenshot-exempt label if this PR has no visible output (e.g. pure docs, CI config).).

Fix the issues above and push an update — the bot will re-review automatically.

Note: This bot is still in beta and might not always work as expected. Please share any feedback via Slack.

@DmitriyAlergant

Copy link
Copy Markdown
Contributor Author

@greptile can you re-review? All concerns were addressed, can you update your review comment?

@oss-pr-review-agent-shin

Copy link
Copy Markdown
Contributor

🤖 litellm-agent: This PR is currently BLOCKED from merge.

Score: 3/5

Why blocked:

  • 1 PR-related CI failure (This PR will be auto-closed as it lacks a screenshot for proof of fix. Please include one in the PR description. Add the screenshot-exempt label if this PR has no visible output (e.g. pure docs, CI config).) (pr_related_failures, -2 pts)

Details: Score docked for: 1 PR-related CI failure (This PR will be auto-closed as it lacks a screenshot for proof of fix. Please include one in the PR description. Add the screenshot-exempt label if this PR has no visible output (e.g. pure docs, CI config).).

Fix the issues above and push an update — the bot will re-review automatically.

Note: This bot is still in beta and might not always work as expected. Please share any feedback via Slack.

@DmitriyAlergant
DmitriyAlergant force-pushed the codex/gemini-image-usage-routing branch from 48f4b9e to 5b300a9 Compare May 19, 2026 21:48
@DmitriyAlergant DmitriyAlergant changed the title Codex/gemini image usage routing gemini image models fixes in /images/generations and /images/edits: usage logging, spend calculation, passing size params May 20, 2026
@DmitriyAlergant
DmitriyAlergant force-pushed the codex/gemini-image-usage-routing branch from 3b62727 to 1723145 Compare June 2, 2026 01:33
@CLAassistant

CLAassistant commented Jun 2, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@DmitriyAlergant
DmitriyAlergant force-pushed the codex/gemini-image-usage-routing branch from 1723145 to b3ce706 Compare June 2, 2026 01:38
@DmitriyAlergant
DmitriyAlergant changed the base branch from litellm_internal_staging to litellm_oss_staging June 2, 2026 01:39
@DmitriyAlergant
DmitriyAlergant force-pushed the codex/gemini-image-usage-routing branch from b3ce706 to 61a51a1 Compare June 2, 2026 01:48
@mateo-berri
mateo-berri deleted the branch BerriAI:litellm_oss_staging June 2, 2026 15:48
@mateo-berri mateo-berri closed this Jun 2, 2026
@Sameerlite Sameerlite reopened this Jun 11, 2026
@Sameerlite
Sameerlite requested a review from a team June 11, 2026 14:48
@Sameerlite Sameerlite closed this Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Cannot generate 2K images with Gemini 3.1 Flash Image Preview (stuck at 1K) - extra_body is stripped

4 participants