Skip to content

fix(moonshot): preserve image_url blocks in multimodal messages - #21595

Merged
Chesars merged 1 commit into
BerriAI:litellm_oss_staging_02_27_2026from
Chesars:fix/moonshot-preserve-image-url-content
Feb 27, 2026
Merged

Chesars merged 1 commit into
BerriAI:litellm_oss_staging_02_27_2026from
Chesars:fix/moonshot-preserve-image-url-content

Conversation

@Chesars

@Chesars Chesars commented Feb 19, 2026 •

Copy link
Copy Markdown
Contributor

Relevant issues

Fixes #20862

Pre-Submission checklist

  • I have Added testing in the tests/litellm/ directory, Adding at least 1 test is a hard requirement
  • 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

🐛 Bug Fix
📖 Documentation

Changes

Moonshot's _transform_messages unconditionally flattened content arrays to plain strings via handle_messages_with_content_list_to_str_conversion(), dropping all non-text content blocks (image_url, input_audio, video_url, file, etc.). Multimodal models like kimi-k2.5 accept the standard OpenAI content array format.

Fix: Before flattening, check if any message contains a non-text content part (type != "text"). If so, skip flattening and preserve the content array. If all parts are text-only, flatten as before (required by Moonshot text models). This covers the full OpenAI content spec, not just images.

Example request

import litellm

response = litellm.completion(
    model="moonshot/kimi-k2.5",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What is in this image?"},
                {
                    "type": "image_url",
                    "image_url": {"url": "https://example.com/image.png"},
                },
            ],
        }
    ],
)

Before fix: the content array was flattened to the string "What is in this image?" — the image_url block was dropped.

After fix: the content array is preserved as-is, and the multimodal payload reaches the Moonshot API.

Files changed

  • litellm/llms/moonshot/chat/transformation.py — Skip flattening when any content part has type != "text"
  • tests/test_litellm/llms/moonshot/test_moonshot_chat_transformation.py — 3 new tests: image_url preserved, input_audio preserved, text-only flattened
  • docs/my-website/docs/providers/moonshot.md — Add "Image / Vision Support" section with usage example

@vercel

vercel Bot commented Feb 19, 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 Feb 19, 2026 7:46pm

Request Review

Moonshot's _transform_messages unconditionally flattened content arrays
to plain text, dropping image_url blocks. Vision models like kimi-k2.5
accept the standard OpenAI content array format.

Now checks for image_url blocks before flattening — if any message
contains images the content array is preserved intact.

Fixes BerriAI#20862
@Chesars
Chesars force-pushed the fix/moonshot-preserve-image-url-content branch from a780b8f to c5cec60 Compare February 19, 2026 19:44
@greptile-apps

greptile-apps Bot commented Feb 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a bug where Moonshot's _transform_messages was unconditionally flattening content arrays to strings, causing image_url blocks to be silently dropped for vision models like kimi-k2.5.

Key changes:

  • Added detection logic to check if any message contains an image_url block before flattening
  • If images are present, content arrays are preserved; otherwise, they're flattened to strings as required by text-only models
  • Pattern mirrors the Mistral provider implementation (lines 250-259 in litellm/llms/mistral/chat/transformation.py)
  • Two new tests validate both the image preservation and text flattening behavior
  • Documentation updated with vision support section and usage example

The fix is minimal, focused, and maintains backward compatibility for text-only requests while enabling vision capabilities.

Confidence Score: 5/5

  • This PR is safe to merge with no issues found
  • The fix is minimal, well-tested, follows the exact pattern used by Mistral provider, and addresses a specific bug where image_url blocks were being dropped. Tests cover both the positive case (image preservation) and negative case (text flattening).
  • No files require special attention

Important Files Changed

Filename Overview
litellm/llms/moonshot/chat/transformation.py Adds image_url detection logic to preserve content arrays for vision models while maintaining text-only flattening for other models
tests/test_litellm/llms/moonshot/test_moonshot_chat_transformation.py Adds two comprehensive tests for image_url preservation and text-only flattening behavior
docs/my-website/docs/providers/moonshot.md Adds clear documentation section for vision support with usage example

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User calls litellm.completion] --> B[MoonshotChatConfig._transform_messages]
    B --> C{Check all messages for image_url}
    C -->|Has image_url| D[Skip flattening]
    C -->|No image_url| E[Call handle_messages_with_content_list_to_str_conversion]
    D --> F[Content array preserved]
    E --> G[Content flattened to string]
    F --> H[Send to Moonshot Vision API]
    G --> I[Send to Moonshot Text API]
    H --> J[Image reaches API successfully]
    I --> K[Text-only request processed]
Loading

Last reviewed commit: c5cec60

@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.

3 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@Chesars
Chesars changed the base branch from main to litellm_oss_staging_02_27_2026 February 27, 2026 20:46
@Chesars
Chesars merged commit 1552775 into BerriAI:litellm_oss_staging_02_27_2026 Feb 27, 2026
9 of 21 checks passed
@Chesars
Chesars deleted the fix/moonshot-preserve-image-url-content branch February 27, 2026 20:47
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
…mage-url-content

fix(moonshot): preserve image_url blocks in multimodal messages

This branch was successfully deployed

1 active deployment
Preview — c5cec60f Deployed Feb 19, 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.

[Bug]: Moonshot dropping images from list of messages

1 participant