【DO NOT MERGE】fix(providers): stop sending media to SiliconFlow DeepSeek V4 - #7247
【DO NOT MERGE】fix(providers): stop sending media to SiliconFlow DeepSeek V4#7247rayrayraykk wants to merge 1 commit into
Conversation
|
Hi @rayrayraykk, this is your 260th Pull Request. 🎁 Milestone Celebration🏆🏆🎖️🏅 Congratulations! This is your 260th contribution. Thank you for your continued support! You're an important member of the QwenPaw community! 🐾 📋 About PR TemplateTo help maintainers review your PR faster, please make sure to include:
Complete PR information helps speed up the review process. You can edit the PR description to add these details. 🙌 Join Developer CommunityThanks so much for your contribution! We'd love to invite you to join the official QwenPaw developer group! You can find the Discord and DingTalk group links under the "Developer Community" section on our docs page: We truly appreciate your enthusiasm—and look forward to your future contributions! 😊 We'll review your PR soon. |
There was a problem hiding this comment.
Pull request overview
This PR fixes excessive request growth and memory pressure when using SiliconFlow’s dynamically discovered DeepSeek V4 models by ensuring the packaged “text-only” capability annotations apply to namespaced model IDs (e.g. deepseek-ai/DeepSeek-V4-*) immediately during the discovery transaction. This prevents historical screenshot/media blocks from being included in subsequent text-only requests when capability was previously None (fail-open).
Changes:
- Add SiliconFlow (
siliconflow-cnandsiliconflow-intl) capability-baseline entries markingdeepseek-ai/DeepSeek-V4-Flashanddeepseek-ai/DeepSeek-V4-Proas non-visual (text-only). - Apply documentation-based annotations to discovered models (and do so during discovery snapshot persistence), while preserving probed and already-configured capability values.
- Add regression tests covering both SiliconFlow regions and both DeepSeek V4 namespaced IDs to ensure discovered models are immediately annotated as text-only.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| tests/unit/providers/test_siliconflow_provider.py | Adds discovery regression tests asserting DeepSeek V4 discovered models are annotated as text-only with probe_source=documentation. |
| src/qwenpaw/providers/provider_manager_discovery.py | Applies capability annotations to the discovery snapshot before it is merged/persisted, so discovered models are corrected immediately. |
| src/qwenpaw/providers/provider_annotations.py | Extends annotation application to include discovered_models in addition to configured models. |
| src/qwenpaw/providers/data/model_capabilities.json | Updates catalog version/date and adds text-only capability expectations for the SiliconFlow DeepSeek V4 Flash/Pro model IDs. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Summary
SiliconFlow discovers models dynamically with namespaced IDs such as
deepseek-ai/DeepSeek-V4-Flash. The packaged text-only annotations only covered the separatedeepseekprovider and unnamespaced IDs, so the SiliconFlow models remainedsupports_multimodal=None.Unknown capability intentionally fails open. As a result, every new model call cloned, formatted, JSON-encoded, and uploaded every historical screenshot in the session even though SiliconFlow's DeepSeek V4 Pro/Flash models are text-only. The current response does not need to contain an image: old tool-result images in the live session are enough to make a new request large before/while the UI shows
Thinking.This PR:
deepseek-ai/DeepSeek-V4-Flashanddeepseek-ai/DeepSeek-V4-Proas text-only for bothsiliconflow-cnandsiliconflow-intl;SiliconFlow's model catalog lists tool calling for these two models but does not list visual input; its visual models carry a separate visual-input capability: https://www.siliconflow.cn/models
User-visible failure chain
DataBlocks across long agent/tool loops.Thinkingblock while the backend is under memory pressure.This is independent of the two streaming fixes already merged today:
+=accumulation for long text/reasoning deltas.Both are valid, but neither prevents historical screenshots from entering a text-only SiliconFlow request. This PR does not drop tool chunks or change the SSE/frontend protocol.
Reproduction
The benchmark used the real QwenPaw OpenAI formatter, AgentScope
OpenAIChatModel, and the OpenAI Python SDK against a local OpenAI-compatible streaming server. The server read the request without retaining it and returned reasoning deltas. Each simulated screenshot was a 1 MiB image in a historicalToolResultBlock; the same process made 15 calls while history grew from 4 to 60 images.macOS, Python 3.12; values are backend RSS measured from the initialized model/session:
A separate single-call boundary test with 130 historical images at 1.95 MiB each produced a 338.1 MiB request and +463.4 MiB client peak RSS before the fix. With media stripping, request size stays approximately constant (about 53 KiB for 130 history entries).
The mock is intentionally shaped like the reported workload: one session, historical screenshots/tool results, a new response that emits only reasoning, and an OpenAI-compatible DeepSeek endpoint. It does not rely on impossible concurrent unfinished tasks or cumulative provider deltas.
Scope of the 12 GiB observation
I reproduced the monotonic per-turn RSS growth mechanism and the text-only control removes it. I did not reproduce exactly 12 GiB on macOS, and no Windows heap dump is available, so this PR does not claim this is the only allocation source in that specific process. Reaching 12 GiB depends on the number/size of retained media blocks, repeated turns, allocator behavior, and in-flight provider latency. The reported Windows session had many screenshots and long agent loops, which is the workload this fix bounds.
ReMe auto-memory is not the source of these image bytes in 0.4.1.5: it removes Base64 data before session JSONL persistence, and its history prompt uses text content only.
Tests
supports_image=False,supports_video=False,supports_multimodal=False, andprobe_source=documentation.163 passed, 1 skippedfor SiliconFlow, capability catalog, and ProviderManager tests after rebasing onto currentmain.749 passed, 1 skippedacross provider and formatter/message-normalization regression suites before the final rebase.