Skip to content

feat(openrouter): add image edit support for OpenRouter models - #22403

Merged
Chesars merged 4 commits into
BerriAI:litellm_oss_staging_03_03_2026from
shivaaang:fix/openrouter-image-edit
Mar 3, 2026
Merged

Chesars merged 4 commits into
BerriAI:litellm_oss_staging_03_03_2026from
shivaaang:fix/openrouter-image-edit

Conversation

@shivaaang

@shivaaang shivaaang commented Feb 28, 2026 •

Copy link
Copy Markdown
Contributor

Relevant issues

Fixes #22305

Pre-Submission checklist

  • I have Added testing in the tests/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
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

Type

New Feature

Changes

Problem

OpenRouter models (e.g., google/gemini-2.5-flash-image) support image editing through their chat completions endpoint, but LiteLLM has no image edit configuration for the OpenRouter provider. Calling litellm.image_edit() with an OpenRouter model raises ValueError("image edit is not supported for openrouter") because ProviderConfigManager.get_provider_image_edit_config() returns None for OpenRouter.

Solution

Added OpenRouterImageEditConfig that implements BaseImageEditConfig to route image edit requests through OpenRouter's chat completions endpoint. Unlike providers with dedicated /images/edits endpoints, OpenRouter handles image editing via /api/v1/chat/completions with the source image sent as a base64 data URL in the message content and modalities: ["image", "text"] to signal image output.

  • Converts source images (bytes, BytesIO, BufferedReader) to base64 data URLs in the messages array
  • Maps OpenAI parameters: size to image_config.aspect_ratio, quality to image_config.image_size
  • Parses edited images from choices[].message.images[] in the response
  • Tracks usage including input image tokens from prompt_tokens_details
  • Extracts cost and cost details from OpenRouter's usage response
  • Uses JSON requests (use_multipart_form_data() = False), matching the Gemini image edit pattern
  • Registered in ProviderConfigManager.get_provider_image_edit_config() following the existing factory pattern

Files changed

  • litellm/llms/openrouter/image_edit/__init__.py - New module with factory function get_openrouter_image_edit_config()
  • litellm/llms/openrouter/image_edit/transformation.py - OpenRouterImageEditConfig class with request/response transformation, parameter mapping, usage/cost extraction
  • litellm/utils.py - Added OpenRouter case to ProviderConfigManager.get_provider_image_edit_config()
  • tests/test_litellm/llms/openrouter/image_edit/__init__.py - Test module init
  • tests/test_litellm/llms/openrouter/image_edit/test_openrouter_image_edit_transformation.py - 33 unit tests

Testing

  • 33 new unit tests covering: supported params, multipart mode, parameter mapping (size, quality, n, combined, unknown), size-to-aspect-ratio mapping, quality-to-image-size mapping, URL construction, environment validation, request transformation (basic, BytesIO, multiple images, optional params, base64 encoding, no prompt), response transformation (base64, URL, usage/cost, multiple images, JSON error), error class, and _read_image_bytes edge cases
  • All 33 new tests pass
  • All 48 existing OpenRouter tests continue to pass (81 total)
  • Live-tested against the OpenRouter API with google/gemini-2.5-flash-image, successfully editing an image and receiving a valid response with correct usage tracking

@greptileai @shin-bot-litellm

OpenRouter supports image editing through its chat completions endpoint
for models like google/gemini-2.5-flash-image, but LiteLLM raised
ValueError("image edit is not supported for openrouter") because
OpenRouter was not registered as an image edit provider.

Add OpenRouterImageEditConfig that routes image edit requests through
the chat completions endpoint with the source image as a base64 data
URL in the message content array.

Fixes BerriAI#22305
@vercel

vercel Bot commented Feb 28, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Ready Ready Preview, Comment Mar 3, 2026 6:17pm

Request Review

@greptile-apps

greptile-apps Bot commented Feb 28, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds image edit support for OpenRouter by implementing OpenRouterImageEditConfig that routes litellm.image_edit() calls through OpenRouter's chat completions endpoint. Source images are base64-encoded into the message content with modalities: ["image", "text"], and edited images are extracted from choices[].message.images[] in the response.

  • New OpenRouterImageEditConfig class in litellm/llms/openrouter/image_edit/ implementing BaseImageEditConfig with request/response transformation, OpenAI parameter mapping (size → aspect_ratio, quality → image_size), and usage/cost tracking
  • Registered in ProviderConfigManager.get_provider_image_edit_config() following the existing factory pattern
  • 33 comprehensive mock-only unit tests covering all methods and edge cases
  • Documentation for both SDK and proxy usage added to image_edits.md and providers/openrouter.md
  • Implementation closely mirrors the existing OpenRouterImageGenerationConfig, reusing the same response parsing and cost extraction patterns

Confidence Score: 4/5

  • This PR is safe to merge — it's a purely additive feature with no changes to existing behavior and comprehensive test coverage.
  • Score reflects a clean, well-structured implementation that follows established patterns from the existing OpenRouter image generation config and other image edit providers. All provider-specific code stays within the llms/ directory. 33 mock-only unit tests provide good coverage. The only minor concern is code duplication with the image generation config (shared mapping tables and response parsing logic), but this is consistent with how the codebase handles these features.
  • No files require special attention. The main implementation file litellm/llms/openrouter/image_edit/transformation.py is well-structured and follows codebase conventions.

Important Files Changed

Filename Overview
litellm/llms/openrouter/image_edit/transformation.py New OpenRouterImageEditConfig implementing BaseImageEditConfig. Well-structured with request/response transformation, parameter mapping, usage/cost extraction. Follows existing image generation config patterns closely.
litellm/utils.py Adds OpenRouter case to get_provider_image_edit_config factory method. Follows the exact same lazy-import pattern as all other providers.
tests/test_litellm/llms/openrouter/image_edit/test_openrouter_image_edit_transformation.py 33 comprehensive unit tests covering all methods. Mock-only (no network calls), testing parameter mapping, request/response transformation, edge cases, and error handling.
docs/my-website/docs/image_edits.md Documentation updates adding OpenRouter to the supported providers table and SDK/proxy usage examples.
docs/my-website/docs/providers/openrouter.md Provider-specific documentation for OpenRouter image edit including supported models, parameter mapping table, and usage examples.

Sequence Diagram

sequenceDiagram
    participant Client
    participant LiteLLM as litellm.image_edit()
    participant PCM as ProviderConfigManager
    participant Config as OpenRouterImageEditConfig
    participant OR as OpenRouter API

    Client->>LiteLLM: image_edit(model, image, prompt)
    LiteLLM->>PCM: get_provider_image_edit_config("openrouter")
    PCM-->>LiteLLM: OpenRouterImageEditConfig
    LiteLLM->>Config: validate_environment(headers, api_key)
    Config-->>LiteLLM: headers with Bearer token
    LiteLLM->>Config: map_openai_params(size, quality, n)
    Config-->>LiteLLM: image_config.aspect_ratio, image_config.image_size
    LiteLLM->>Config: transform_image_edit_request(model, prompt, image)
    Note over Config: Base64-encode image into<br/>chat completion message content
    Config-->>LiteLLM: {model, messages, modalities: ["image","text"]}
    LiteLLM->>OR: POST /api/v1/chat/completions
    OR-->>LiteLLM: {choices, usage, cost}
    LiteLLM->>Config: transform_image_edit_response(raw_response)
    Note over Config: Extract images from<br/>choices[].message.images[]<br/>Set usage and cost
    Config-->>LiteLLM: ImageResponse(data, usage)
    LiteLLM-->>Client: ImageResponse
Loading

Last reviewed commit: fecb301

@greptile-apps greptile-apps Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment thread litellm/llms/openrouter/image_edit/transformation.py
Raise ValueError when OPENROUTER_API_KEY is not set instead of
sending "Bearer None" and getting a confusing 401 from the API.
@CLAassistant

CLAassistant commented Mar 2, 2026 •

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
0 out of 2 committers have signed the CLA.

❌ Shivaang
❌ Chesars


Shivaang seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

Add OpenRouter image edit docs to both the provider page and the
main image_edits reference page, including supported models, parameter
mappings (size→aspect_ratio, quality→image_size), usage examples,
proxy configuration, and a note about 4K quality model support.
Comment thread litellm/llms/openrouter/image_edit/transformation.py Outdated
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
@Chesars
Chesars changed the base branch from main to litellm_oss_staging_03_03_2026 March 3, 2026 18:30
@Chesars
Chesars merged commit 8a1e915 into BerriAI:litellm_oss_staging_03_03_2026 Mar 3, 2026
3 of 36 checks passed
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
…edit

feat(openrouter): add image edit support for OpenRouter models

This branch was successfully deployed

1 active deployment
Preview — fecb3016 Deployed Mar 3, 2026 by vercel[bot]
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.

[Feature]: Support image edit for OpenRouter models

3 participants