feat: VLM vision analysis - intercept images for text-only models#1405
feat: VLM vision analysis - intercept images for text-only models#1405kanchengw wants to merge 6 commits into
Conversation
72d4264 to
684e24f
Compare
684e24f to
e5f529f
Compare
|
感谢提交。静态审查和本地测试后,目前有几项阻塞合并的问题需要先处理:
本地验证结果:
以上问题修复并补充回归测试后再进行下一轮审查。 |
Strip image_url/input_image blocks, call VLM to describe them, inject descriptions as text. Per-round analysis with LRU cache (500 entries, 24h TTL), depth limit (20 rounds), per-request image cap (10 historical), bounded concurrency (3 per-request, 5 global), HTTP timeouts (connect 5s, request 30s, total 120s). Fail-closed: preserve images when VLM unreachable. 42 tests including 8 wiremock integration tests.
|
感谢审查。VLM 管线采用两阶段分析,逐点回复如下。 1. Responses 模式不经过代理UI 侧已处理: 运行时确认 Codex 请求统一走 2. HTTP 超时超时后未完成的 batch task 被 JoinSet drop 取消,已完成的结果保留。全部失败则返回 Err 走 fail-closed。 3. 历史图片处理(两阶段分析)
Phase 1(同步):
决策矩阵:
Phase 2(后台,仅 X > 10 时启动):
上下文溢出保护: 截断兜底: 所有注入合并 ≤ available × 2 字符上限,超出从远端(最旧轮)砍。 概括: 同步路径覆盖当前轮+黄金窗口(保障核心相关性),后台静默推进深层(零延迟),X 统管所有注入总量,上下文消耗完全可控。 4. fail-closed 策略
各场景处理:
不再可能把上游错误正文注入模型上下文。 5. UI 校验
如需保存时强制阻断(当前为被动警告),请确认。 6. 并发 / 图片上限 / 错误截断
测试测试覆盖类别:
|
- VL 单次调用加 .timeout(30s),10 张图最多 300s - VL_IMAGE_LIMIT=10,超出部分直接 strip 不调 VL API - PR 文档:已知局限更新(去掉已 fix 的超时),新增第十章与 BigPizzaV3#1405 完整对比 - 删除废弃的未命名.txt handoff 文件 Co-Authored-By: Claude <noreply@anthropic.com>
Summary
Add VLM (Vision Language Model) analysis to the protocol proxy. When a text-only model (e.g. DeepSeek V4) receives an image, the proxy strips the image blocks, calls a VLM API (e.g. qwen-vl-plus) to describe the images in the latest user message, and injects the descriptions as text -- enabling text-only models to see images without upstream errors. Furthermore, with VLM analysis enabled for a text-only model in the manager, previously corrupt sessions are recovered automatically since the proxy strips images from all messages (including history) on every request, and only calls VLM when latest user message includes images.
Closes #574 - DeepSeek session permanently broken by images
Closes #1191 - Feature request: auto-intercept images for non-vision models
Closes #631 #790 #1158 #1221 #1365 #839 #703 #1194 - unknown variant image_url deserialization errors
How it works
Vision analysis covers:
Together these cover the user's primary intents when sending images in a chat:
The original
image_urlblock is removed entirely. Only the text description remains, ensuring the text-only model can process the message without issues.Why not route the entire conversation to a vision model?
The proxy applies VLM at the network layer without changing the user's model, session, or tool configuration. This preserves full conversation context, avoids dual-model latency/cost, and requires zero changes to Codex Desktop or upstream APIs. Per-model VLM toggles also allow fine-grained control (e.g. flash with VLM, pro without) within the same supplier.
In contrast, routing the entire conversation to a vision model introduces a context dilemma: sending the full history burns excessive tokens on the vision model, while sending only the latest message strips the vision model of the context needed to understand the user's intent.
Files Changed
12 files, +587 / -71。
vision.rs (new, ~304 lines)
Core VLM pipeline with 13 unit tests:
Key design: collect BEFORE strip. Only the latest user message images are VLM-analyzed.
protocol_proxy.rs - Two interception points (+59/-15)
5-condition guard: model non-empty, should_process true, api_key/model/base_url non-empty.
Config and UI
Testing
cargo test -p codex-plus-core vision:: --lib -> 13 passed
node --test src/model-windows.test.ts -> 10 passed
cargo clippy -p codex-plus-core -> clean