Skip to content

fix(openai_api_compatible): fix image query and raw base64 images in multimodal rerank - #4079

Merged
crazywoola merged 1 commit into
langgenius:mainfrom
PeihuaChen:fix/openai-compatible-multimodal-rerank-image
Oct 26, 2026
Merged

crazywoola merged 1 commit into
langgenius:mainfrom
PeihuaChen:fix/openai-compatible-multimodal-rerank-image

Conversation

@PeihuaChen

@PeihuaChen PeihuaChen commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Summary

No existing issue tracks this bug; the failure was reproduced and verified directly against a self-hosted vLLM endpoint (details below).

Fixes multimodal rerank in the openai_api_compatible plugin when the query or the documents are images (verified against vLLM v0.31.0 serving a Qwen3-VL-Reranker model via /v1/rerank).

Two problems in _invoke_multimodal:

  1. Image query is inlined into the text query. The plugin assumed Qwen3-VL-Reranker does not support image queries and sent "query": "[Image: <base64>]". A real image is tens/hundreds of KB of base64, so the prompt exceeds the context window and vLLM answers HTTP 400:

    This model's maximum context length is 32768 tokens. However, ... your prompt contains at least 32769 input tokens.

    vLLM actually accepts an image query in the same ScoreMultiModalParam format as documents ({"content": [{"type": "image_url", ...}]}), so it is now sent that way.

  2. Raw base64 document images are silently dropped. Dify passes images to the plugin as raw base64 (no data: prefix). _validate_image_url only allows http(s) / data:image, so these were turned into empty {"content": []} documents (and sending raw base64 to vLLM directly yields The URL must be either a HTTP, data or file URL).

Changes (all in models/openai_api_compatible):

  • Send an image query as ScoreMultiModalParam; text queries are still a plain string.

  • New _normalize_image_url: wraps raw base64 into data:image/<fmt>;base64,... after detecting the format from magic bytes (png/jpeg/gif/webp/bmp). URLs and existing data URIs are untouched; anything that is not a known image stays as-is and is still rejected by _validate_image_url.

  • Raise InvokeBadRequestError for an invalid/unsupported image query instead of calling the endpoint.

  • SSRF protections are unchanged (file://, localhost and private IPs are still blocked).

  • Added tests/test_rerank_multimodal_image.py.

Release Notes

  • Fix: multimodal rerank with an image query no longer fails with HTTP 400 on vLLM/Qwen3-VL-Reranker (the image is now sent as an image instead of being embedded as text).

  • Fix: images from Dify knowledge-base documents (raw base64) are now actually passed to the rerank model instead of being dropped.

Change Type

  • Documentation / non-plugin change

  • Non-LLM plugin (tools, extensions, datasource, etc.)

  • LLM plugin

Screenshots / Videos

Dify knowledge base hit testing with an image query against a vLLM-hosted Qwen3-VL reranker (/v1/rerank):

| Before | After |

| ------ | ----- |

| Rerank API request failed (HTTP 400) (vLLM: maximum context length is 32768 tokens ... at least 32769 input tokens) | Request succeeds; identical image scores highest (0.9583 vs 0.5325 for a different image and 0.0554 for unrelated text) |

LLM Plugin Checklist

Areas affected by this change (check all that apply)
  • Message flow (system messages, user ↔ assistant turn-taking)

  • Tool interaction flow (multi-round usage, Agent App and Agent Node)

  • Multimodal input (images, PDFs, audio, video, etc.)

  • Multimodal output (images, audio, video, etc.)

  • Structured output (JSON, XML, etc.)

  • Token consumption metrics

  • Other LLM functionality (reasoning, grounding, prompt caching, etc.)

  • New models / model parameter fixes

Version

Testing

  • Local deployment — Dify version: 1.14.2 (self-hosted, vLLM v0.31.0 serving a Qwen3-VL reranker). Installed the packaged plugin and ran knowledge-base hit testing with image queries.

  • SaaS (cloud.dify.ai)

Also:

  • Existing tests/test_rerank_authorization.py (16 tests) and the new tests/test_rerank_multimodal_image.py pass (26 tests total). Tests were run with Python 3.11 and dify_plugin==0.7.4, not the Python 3.12 / uv.lock environment, so please let CI confirm.

  • Called OpenAIRerankModel._invoke_multimodal directly against the vLLM endpoint with ~100 KB base64 images: image query + image docs, image query + text docs, text query + image docs and text query + text docs all return 200; an invalid image query raises InvokeBadRequestError.

@crazywoola

Copy link
Copy Markdown
Member

Hi @PeihuaChen, thanks for fixing the image query and raw base64 images in multimodal rerank!

Heads-up about models/openai_api_compatible/manifest.yaml: the consolidated dependency refresh (#4106–#4111) bumped it to 0.0.69 on main, and several PRs are currently open for this plugin from different authors (#3795, #3869, #4060, #4066, #4068). Please rebase on latest main and bump the version to the next unused one so the releases don't collide. If there's a related issue for this fix, linking it in the description would help too.

Thanks again! 🙏

…correctly in multimodal rerank

- Send an image query as a ScoreMultiModalParam (image_url) instead of
  inlining "[Image: <base64>]" into the text query, which overflowed the
  model context window (HTTP 400 from vLLM Qwen3-VL-Reranker).
- Wrap raw base64 images (as passed by Dify) into data URIs so they are no
  longer dropped by URL validation and sent as empty documents.
- Raise InvokeBadRequestError for an invalid image query.
- Bump version to 0.0.71 (0.0.69 is on main, 0.0.70 is claimed by langgenius#4066).
@PeihuaChen
PeihuaChen force-pushed the fix/openai-compatible-multimodal-rerank-image branch from 5c49b12 to 08ffa91 Compare October 26, 2026 02:16
@PeihuaChen

Copy link
Copy Markdown
Contributor Author

Thanks for the heads-up! Rebased on latest main (37722e8) and bumped manifest.yaml to 0.0.71, since 0.0.69 is already on main and 0.0.70 is taken by #4066. The PR is still a single commit touching manifest.yaml, models/rerank/rerank.py and the new tests/test_rerank_multimodal_image.py.

I couldn't find an existing issue for this bug. I hit it and reproduced it directly against a self-hosted vLLM Qwen3-VL reranker, and I've added a note about that to the description.

@crazywoola
crazywoola deployed to models/openai_api_compatible October 26, 2026 03:36 — with GitHub Actions Active
@crazywoola
crazywoola merged commit ba9600d into langgenius:main Oct 26, 2026
4 checks passed

This branch was successfully deployed

1 active deployment
models/openai_api_compatible — 08ffa919 Deployed Oct 26, 2026 by crazywoola via test (models/openai_api_compatible) #2917
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.

2 participants