Skip to content

fix(provider): treat deepseek-flash as native multimodal - #4467

Closed
jaychou0642-create wants to merge 1 commit into
lidge-jun:devfrom
jaychou0642-create:fix/deepseek-flash-native-vision-4436
Closed

fix(provider): treat deepseek-flash as native multimodal#4467
jaychou0642-create wants to merge 1 commit into
lidge-jun:devfrom
jaychou0642-create:fix/deepseek-flash-native-vision-4436

Conversation

@jaychou0642-create

@jaychou0642-create jaychou0642-create commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #4436.

  • Treat first-party deepseek-flash as native multimodal by default:
    • Drop deepseek-flash from first-party DeepSeek's noVisionModels in src/providers/registry.ts.
    • Add positive modality declaration modelInputModalities: { "deepseek-flash": ["text", "image"] }.
    • Keep legacy preview alias deepseek-v4-flash-vision-exp and first-party compatibility aliases (deepseek-chat, deepseek-reasoner, deepseek-v4-flash) unchanged.
    • Gateway routes (Zen / OpenCode Go / Volcengine / Alibaba) remain unchanged and unprobed.
  • Upgrade / configuration boundary:
    • Router and catalog resolution honor user-configured noVisionModels or explicit modelCapabilities overrides.
    • Users with existing saved configs containing deepseek-flash in noVisionModels can simply remove the entry to unlock native vision.
  • Documentation & SSOT:
    • Updated English, zh-CN, zh-TW, French, and Turkish provider guides as well as sidecars docs.
    • Updated structure SSOT documents (runtime.md, subagents.md, transports/inventory.md, providers/xai-grok.md).

Verification

  • Local testing with Bun 1.4.2 against isolated fixtures:
    • bun test tests/providers/provider-registry-parity.test.ts: 52 pass, 0 fail (covers deepseek-flash native modality, sidecar bypass, and legacy saved config upgrade/override behavior).
    • bun test tests/vision/vision-sidecar-e2e.test.ts: passed all relevant cases including new tests proving deepseek-flash preserves images on both openai-chat and openai-responses wires with zero sidecar calls.
    • bun test tests/vision/vision-eligibility.test.ts: 18 pass, 0 fail.
    • bun test tests/vision/vision-text-only-predicate.test.ts: 9 pass, 0 fail.
  • Structure SSOT & Privacy:
    • bun run structure:check: passed.
    • bun run privacy:scan: passed.
    • git diff --check: passed.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

  • New Features
    • DeepSeek Flash now supports native image inputs, sending image requests directly to DeepSeek by default.
    • Explicit configuration overrides remain authoritative, while other DeepSeek models continue using the vision sidecar by default.
  • Documentation
    • Updated provider, runtime, sidecar, transport, and multilingual documentation to describe DeepSeek image-routing behavior.
  • Bug Fixes
    • Preserved native image content without unnecessary sidecar processing for DeepSeek Flash requests.

Closes lidge-jun#4436.

- Remove 'deepseek-flash' from first-party DeepSeek's 'noVisionModels'.
- Declare native 'text' and 'image' input in 'modelInputModalities'.
- Keep compatibility aliases ('deepseek-chat', 'deepseek-reasoner', 'deepseek-v4-flash') and Zen gateway routes unchanged.
- Update docs and structure SSOT files accordingly.
- Add focused registry and end-to-end vision sidecar regression tests.
@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 608b854f-6082-4592-bbe1-16f5f5f53b64

📥 Commits

Reviewing files that changed from the base of the PR and between 9cbad1b and 1b44ede.

📒 Files selected for processing (13)
  • docs-site/src/content/docs/fr/guides/providers.md
  • docs-site/src/content/docs/guides/providers.md
  • docs-site/src/content/docs/guides/sidecars.md
  • docs-site/src/content/docs/tr/guides/providers.md
  • docs-site/src/content/docs/zh-cn/guides/providers.md
  • docs-site/src/content/docs/zh-tw/guides/providers.md
  • src/providers/registry.ts
  • structure/providers/xai-grok.md
  • structure/runtime.md
  • structure/subagents.md
  • structure/transports/inventory.md
  • tests/providers/provider-registry-parity.test.ts
  • tests/vision/vision-sidecar-e2e.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The DeepSeek registry now treats deepseek-flash as natively multimodal. Tests verify routing and image preservation. Provider and runtime documentation now describes the updated behavior.

Changes

DeepSeek native vision routing

Layer / File(s) Summary
Update DeepSeek model classification
src/providers/registry.ts
deepseek-flash now declares text and image inputs and is removed from noVisionModels. Other listed DeepSeek models remain sidecar-backed.
Validate registry and saved-provider routing
tests/providers/provider-registry-parity.test.ts
Tests cover modalities, sidecar eligibility, gateway aliases, fresh configurations, and saved configurations with the previous classification.
Validate upstream image preservation
tests/vision/vision-sidecar-e2e.test.ts
Tests cover openai-chat and openai-responses wires. Native image data reaches the upstream request without sidecar calls or omission markers.
Document provider and sidecar behavior
docs-site/src/content/docs/..., structure/...
Localized provider guides and runtime documentation describe native deepseek-flash image handling, retained sidecar defaults, override precedence, and unchanged Zen routing.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 1b44e

DeepSeek Flash image requests are classified for native forwarding while existing override and legacy-routing behavior remains covered. No actionable merge risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 3 files. (10 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Issue #4436 requires native multimodal classification for deepseek-flash, unchanged forwarding of images, catalog image support, preservation of text-only classifications for deepseek-chat, `deeps…
Out of Scope Changes check ✅ Passed The changed files are connected to Issue #4436. src/providers/registry.ts contains the provider behavior. The registry parity and vision sidecar end-to-end tests verify the required routing and comp…
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: treating deepseek-flash as a native multimodal provider model.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 3 files. (10 skipped: 10 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the bug Something isn't working label Sep 13, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions

github-actions Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed; the review readiness checklist is complete.

Review readiness checklist

  • ✅ All CI tests are green on my local testing.
  • ✅ I pushed my PR to the latest dev commit.
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

4/4 boxes ticked.

This pull request is already Ready for Review.
The review-ready label marks this PR as ready; review automation runs independently.
Maintainers: @lidge-jun @Ingwannu

@github-actions
github-actions Bot marked this pull request as ready for review September 13, 2026 06:08
@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 68 / 80

설명
이 PR은 열린 버그 #4436을 고친다. DeepSeek first-party 기본 모델 deepseek-flash(V4.1-Flash)는 이미 Chat Completions와 Responses 양쪽에서 네이티브 이미지 입력을 받는데, 지금까지 OpenCodex 레지스트리는 Issue #88 시절 규칙(“DeepSeek API는 전부 텍스트만”)으로 flash를 noVisionModels에 넣어 두었다. 그래서 이미지가 붙은 요청은 src/vision 사이드카가 먼저 글 설명으로 바꾼 뒤에야 본 모델로 가고, 품질·지연·비용이 모두 나빠졌다. 보고자는 api.deepseek.com에 직접 빨간 PNG / 초록·파랑 반반 PNG를 붙여 200과 올바른 색 답을 받았고, 가짜 URL은 400 “이미지를 못 내려받았다”로 나와서 서버가 진짜로 이미지를 다운로드한다는 증거까지 남겼다.

지금 dev HEAD는 4a84ca22c(#4462, 서브에이전트 표면 기본값을 v1로 두고 base/v2는 승인 후 선택)이고 package는 2.53.0이다. HEAD의 src/providers/registry.ts DeepSeek 엔트리를 보면 이슈 리뷰 때와 같다. modelInputModalities는 실험 id deepseek-v4-flash-vision-exp["text","image"]이고, noVisionModels["deepseek-chat","deepseek-reasoner", ...DEEPSEEK_NATIVE_THINKING_MODELS]라서 flash와 호환 별칭 deepseek-v4-flash가 둘 다 사이드카 소비자다. src/vision/eligibility.tsisModelVisionSidecarConsumernoVisionModels 멤버면 modality보다 먼저 true를 돌려서, 양수 modality만 넣어도 사이드카가 안 꺼진다. src/router.tsmergeStringArray는 레지스트리 seed와 저장 설정을 합집합하므로, 레지스트리에 flash가 남아 있는 한 사용자가 설정에서 빼도 다시 붙는다. 그래서 수정 지점은 레지스트리여야 한다.

이 PR이 하는 일은 그 처방과 거의 같다. first-party 엔트리에서 deepseek-flashnoVisionModels에서 빼고(deepseek-chat/deepseek-reasoner/deepseek-v4-flash는 유지), modelInputModalities["deepseek-flash"] = ["text","image"]를 추가한다. 주석도 #4436과 “config로는 못 지운다”를 명시한다. Zen / OpenCode Go / Volcengine / Alibaba 게이트웨이 행은 건드리지 않았고, 프로브하지 않았다고 문서에 적었다. 테스트는 tests/providers/provider-registry-parity.test.ts에 flash가 사이드카 소비자가 아닌지·게이트웨이 별칭은 그대로인지·예전에 저장된 noVisionModels에 flash가 남아 있으면 사이드카가 유지되는지까지 잠그고, tests/vision/vision-sidecar-e2e.test.ts에서 openai-chat/openai-responses 두 와이어로 이미지가 그대로 upstream에 가고 sidecarHits=0인지 확인한다. docs-site providers/sidecars와 structure SSOT에도 같은 문장을 넣었다. review-ready 라벨이 있고 CI 위생·타깃 브랜치 검사는 통과한 상태다. types/config 분할에 잡아먹힐 변경이 아닌 독립 provider 픽스라 닫지 말고 받는 쪽이 맞다.

우선순위 68은 “기본 DeepSeek 모델의 이미지 경로가 틀려 있던 실사용 버그” 무게와, 범위가 레지스트리+테스트+문서라 위험이 낮은 점의 균형이다. #4462(서브에이전트 v1 기본)와 파일 겹침이 거의 없어 기차에 끼워도 부담이 작다. 다만 PR base가 9cbad1be6(#4466 tip)이라 방금 올라간 4a84ca22c보다 한 커밋 뒤다. 충돌 가능성은 낮지만 머지 전에 dev tip으로 rebase하는 편이 안전하다.

src/providers/registry.ts DeepSeek noVisionModels - flash만 리스트에서 빼고 chat/reasoner/v4-flash는 사이드카에 남긴 선택은 #4436 프로브 범위와 맞다. Issue #88 전면 주석을 #4436 주석으로 바꾼 것도 맞다.

src/providers/registry.ts modelInputModalities["deepseek-flash"] - 양수 선언이 없으면 카탈로그·capability 체인이 native image로 안 읽힐 수 있다. preview id 행을 유지한 것도 보고자 증거(preview→flash 라우팅)와 맞다.

tests/providers/provider-registry-parity.test.ts legacy saved config 케이스 - 예전에 저장된 noVisionModels에 flash가 있으면 사이드카가 남는 동작을 의도적으로 고정한다. 즉 업그레이드만으로는 예전 config.json 사용자가 자동 해제되지 않는다. 스타트업 마이그레이션(옛 seed와 같으면 flash만 제거)이 없다는 점을 메인테이너가 알아야 한다.

tests/vision/vision-sidecar-e2e.test.ts chat/responses 두 와이어 테스트 - 실제 레지스트리의 noVisionModels/modelInputModalities를 loopback fixture에 복사해 sidecarHits=0과 이미지 파트 보존을 본다. 회귀 잠금으로 충분하다.

structure/providers/xai-grok.md / structure/subagents.md - DeepSeek flash vision 문단이 xAI 문서와 서브에이전트 문서에 “이 변경은 여기 영향 없음” 형태로 복사되어 있다. structure:check를 통과시키려는 중복에 가깝고, SSOT 위치가 어색하다. structure/runtime.md·structure/transports/inventory.md·providers 가이드면 충분해 보인다.

docs-site en/zh-cn/zh-tw/fr/tr providers + sidecars - 사용자 가이드 갱신은 좋다. Zen 미프로브·별칭 유지 문장도 이슈 합의와 같다.

심볼 src/router.ts mergeStringArray - 이번 PR이 레지스트리에서 flash를 빼면, 저장 목록에 flash가 없는 사용자는 바로 native vision이 된다. 저장 목록에 옛 seed가 통째로 남아 있는 사용자만 수동 편집이 필요하다. PR body의 “엔트리만 지우면 된다”는 그 경우에 해당한다.

메인테이너의 판단이 필요한 지점

  • 저장된 noVisionModels에서 옛 seed와 일치할 때 deepseek-flash만 한 번 지우는 스타트업 마이그레이션을 같은 PR에 넣을지, 문서/릴리즈 노트 안내만 할지.
  • structure/providers/xai-grok.md·structure/subagents.md의 DeepSeek 문단을 유지할지, runtime/inventory/providers 쪽으로만 좁힐지.
  • deepseek-v4-flash 호환 별칭과 Zen deepseek-v4.1-flash를 follow-up 프로브로 남을지, 같은 기차에 묶을지(PR은 후자 미포함이 맞음).
  • base가 9cbad1be6이므로 Make v1 the default sub-agent surface and ask before base or v2 #4462 tip(4a84ca22c)으로 rebase 후 머지할지.

너의 추천
#4436을 닫는 방향으로 머지 후보다. 로컬에서 bun test tests/providers/provider-registry-parity.test.tsbun test tests/vision/vision-sidecar-e2e.test.ts만 초록 확인한 뒤, 가능하면 dev tip에 rebase하고 넣는다. 마이그레이션은 필수는 아니다. 다만 릴리즈 노트에 “예전에 DeepSeek provider를 저장해 둔 사람은 noVisionModels에서 deepseek-flash를 지우라” 한 줄을 넣자. xai-grok/subagents 문단은 원하면 머지 전·후에 정리해도 된다. Zen·v4-flash 별칭은 별도 프로브 이슈로 남겨 둔다.

이 댓글은 grok-bot이 작성했습니다

lidge-jun added a commit that referenced this pull request Sep 13, 2026
…try seeds

The #4467 carry dropped deepseek-flash from first-party noVisionModels. Update
the minimal persisted-config route assertion so it matches the new seed instead
of issue #88's text-only list.

Refs #4436.
lidge-jun added a commit that referenced this pull request Sep 13, 2026
…epseek-flash-vision

Lane I3 of the contributor carry train: the remaining #3775 catalog defect, and the deepseek-flash native-multimodal fix carried from #4467 by jaychou0642-create.

#4467 was found by the dispatch-time ownership re-check rather than by the candidate harvest — it was opened after the harvest and before this lane, by the person who filed #4436 — so it is carried with a Co-authored-by trailer instead of being reimplemented. That check exists because lane I1 implemented #4442 fresh while contributor draft #4465 had already proposed it.

The #3775 link is an implementation with no source branch. It bounds custom native-id effort lists on gateways, which is what #3804 deliberately left open pending Desktop gateway evidence; the original report is that evidence, since Desktop names gpt-6-astra in the 400 rather than the provider prefix. #4349 and the #4409 ladders do not fix this catalog projection.

Cross-platform CI run 34751593123 concluded success on 9f318cb, the exact head merged here, and it covers both links because the lane is cumulative. #4499 carries no ci check of its own under the owner-authorized tip-only CI economy for this batch.
@lidge-jun

Copy link
Copy Markdown
Owner

Closing as landed, with your credit attached.

Treating deepseek-flash as native multimodal is on dev via #4500 (merge commit 94063d0, verified as an ancestor of origin/dev). Your Co-authored-by trailer is in the landed commit itself rather than only in a description, so it counts on your contributor graph.

Worth saying how this was found: the train that landed it works from a scored inventory of open pull requests, and yours was opened after that snapshot was taken. The lane was originally planned to implement #4436 from scratch. A dispatch-time re-check for an owning pull request caught yours first, so it was carried instead. That check exists because the same thing had already happened once — a contributor draft was superseded without credit — and it will not be the last time a snapshot is stale.

Thanks for filing both the issue and the fix.

@lidge-jun lidge-jun closed this Sep 13, 2026
FacuM pushed a commit to FacuM/opencodex that referenced this pull request Sep 13, 2026
lidge-jun#4436 has an owning contributor pull request, lidge-jun#4467 by jaychou0642-create, opened
after the candidate harvest and before this lane. Lane I3 carries it with a
trailer instead of implementing the fix fresh. This is the wave-1 lidge-jun#4465 lesson
applied as a dispatch-time check rather than a note.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants