Skip to content

fix(registry): declare CommandCode deepseek/deepseek-v4.1-flash natively image-capable - #5039

Merged
lidge-jun merged 1 commit into
lidge-jun:devfrom
xinzhihong-ship-it:fix/command-code-v4.1-flash-native-image
Sep 18, 2026
Merged

lidge-jun merged 1 commit into
lidge-jun:devfrom
xinzhihong-ship-it:fix/command-code-v4.1-flash-native-image

Conversation

@xinzhihong-ship-it

@xinzhihong-ship-it xinzhihong-ship-it commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • command-code now declares deepseek/deepseek-v4.1-flash as natively image-capable: the id moves from COMMAND_CODE_TEXT_ONLY_MODELS (now empty) into COMMAND_CODE_IMAGE_MODELS in src/providers/registry/model-seeds.ts, with the probe evidence recorded at the entry.
  • This is the upstream probe [Provider compatibility] DeepSeek V4.1 Flash and GLM-5.3 Flash modality gaps on OpenCode Go and CommandCode disable combo image input #4505 asked for before promoting the id. opencode-go's route is untouched — it stays text-only and sidecar-covered, because no probe evidence exists for that gateway.
  • The pinned regression tests in tests/providers/flash-route-image-modalities.test.ts are updated for the new classification; the text-only/sidecar mechanism keeps its coverage via the opencode-go route and the hand-made collapse case.

Verification

  • Upstream probe (2026-09-18, @bitkyc08/opencodex 2.58.0 against api.commandcode.ai with a live OAuth account): a 3x3 random-color grid (180x180 PNG, six candidate colors, per-cell random) was delivered twice — as a user-message image and as a tool_result image. Both replies named all nine cells in row-major order exactly (9/9; ~1e-7 by guessing). Both request rows in the proxy usage log show provider=command-code, adapter=command-code, HTTP 200, with no vision-sidecar call in either request window.
  • bun test tests/providers/flash-route-image-modalities.test.ts — 10 pass / 0 fail on the rebased head.
  • bun run typecheck — clean.
  • bun run test (full suite) — 26787 pass / 35 fail on this workstation. Every failure reproduces identically with this change stashed on the same tree (e.g. tests/server/management-provider-validation.test.ts plus tests/lab/lab-fabric-task.test.ts: 165 pass / 21 fail both with and without the change), and the remainder are platform-conditional files (Windows-only paths, keyring-dependent suites). They are environment-only here and unrelated to registry metadata.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed. (No user-facing doc names this per-route classification; docs-site/guides/sidecars.md documents the sidecar mechanism generically, and structure/ names only the context-window hints on this route.)
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults. (Registry metadata and tests only; no auth, credential, or network-path changes.)

Summary by CodeRabbit

  • New Features

    • DeepSeek V4.1-Flash now supports image inputs natively on the command-code route.
    • Image handling is supported for both user messages and tool results.
  • Bug Fixes

    • Corrected the route’s advertised input capabilities to include text and images.
    • Updated capability detection so mixed-model combinations accurately reflect their supported input types.

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.

…pable on CommandCode

Move the id from COMMAND_CODE_TEXT_ONLY_MODELS to COMMAND_CODE_IMAGE_MODELS.
The gateway route was unverified when lidge-jun#4505 classified it text-only; the
upstream probe that issue asked for is now run end to end:

- A 3x3 random-color grid (180x180 PNG, six candidate colors) delivered as a
  user-message image and as a tool_result image both came back 9/9 correct
  (~1e-7 by guessing), with no vision-sidecar call in either request window.
- Both requests: HTTP 200, adapter command-code, on an existing 2.58.0 install.

Update the pinned regression tests for the new classification; opencode-go's
route keeps its text-only declaration (no probe evidence) and the text-only
mechanism stays in place for the next route that measures text-only.
@coderabbitai

coderabbitai Bot commented Sep 18, 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: 5da68dff-be1a-468f-be65-8653e16ed5b7

📥 Commits

Reviewing files that changed from the base of the PR and between a13a908 and c977f32.

📒 Files selected for processing (2)
  • src/providers/registry/model-seeds.ts
  • tests/providers/flash-route-image-modalities.test.ts

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


📝 Walkthrough

Walkthrough

The command-code DeepSeek V4.1-Flash route is moved from the text-only registry to the native image-capable registry. Its derived modalities and tests now expect ["text", "image"]. Combo tests retain their intersection behavior.

Changes

DeepSeek image modality promotion

Layer / File(s) Summary
Registry modality declaration
src/providers/registry/model-seeds.ts
At lines 318–324, the route is added to COMMAND_CODE_IMAGE_MODELS. At lines 344–356, it is removed from COMMAND_CODE_TEXT_ONLY_MODELS, so its derived modalities become ["text", "image"].
Route capability tests
tests/providers/flash-route-image-modalities.test.ts
At lines 5–103, tests and comments distinguish the native command-code route from the sidecar-covered opencode-go route. Assertions now expect native image support for command-code.
Combo modality tests
tests/providers/flash-route-image-modalities.test.ts
At lines 123–154, combo tests use the renamed route constant. Image intersection remains enabled, while an explicit text-only override still collapses the result to ["text"].

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to c977f

The promoted route and its capability tests align, with no actionable current-head risk identified.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: declaring the CommandCode DeepSeek route as natively image-capable. It matches the registry and test updates.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

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.

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 76 / 80

설명

이 PR은 CommandCode 게이트웨이의 deepseek/deepseek-v4.1-flash 경로를 텍스트 전용(비전 사이드카 소비자)에서 네이티브 이미지 가능으로 올리는 레지스트리 메타데이터 수정입니다. 지금 dev(HEAD a13a90819, tip #5032 spend ceiling, package 2.59.0)의 src/providers/registry/model-seeds.ts를 보면 이 id는 COMMAND_CODE_TEXT_ONLY_MODELS에만 들어 있고, COMMAND_CODE_IMAGE_MODELS에는 없습니다. 그래서 COMMAND_CODE_MODEL_INPUT_MODALITIES는 ["text"]를 심고, isModelVisionSidecarConsumer(src/vision/eligibility.ts)는 사이드카 경로를 탑니다. 카탈로그는 사이드카 힌트 덕분에 이미지 입력을 광고하지만, 게이트웨이 자체에 사진을 넘기지는 않습니다.

닫힌 이슈 #4505가 처음에 네 경로(opencode-go / command-code × GLM-5.3-Flash / DeepSeek V4.1-Flash)의 inputModalities 공백을 고쳤을 때, CommandCode DeepSeek 쪽은 검증된 네이티브 비전이 없어 일부러 텍스트 전용으로 남겨 두었습니다. 헤더 주석도 deepseek/deepseek-v4-flash 등은 요청은 받되 이미지를 조용히 버리는 verified-negative라서, 가족 이름만 보고 IMAGE 목록에 넣지 말라고 못 박아 두었습니다. 그래서 #4505는 이 id를 올리기 전에 upstream probe를 하라고 적어 두었고, 이번 PR이 그 증거를 가져옵니다.

변경 내용은 좁습니다. id를 COMMAND_CODE_TEXT_ONLY_MODELS에서 빼 COMMAND_CODE_IMAGE_MODELS로 옮기고, TEXT_ONLY 배열은 빈 [] as const로 남깁니다(메커니즘 자체는 다음 텍스트 전용 경로를 위해 유지). 주석에 2026-09-18 probe 요약을 적었습니다. 180×180 3×3 랜덤 색 격자를 user-message와 tool_result 양쪽에서 보냈을 때 둘 다 9/9로 맞았고, 프록시 사용 로그에 vision-sidecar 호출이 없었다는 주장입니다. opencode-go의 deepseek-v4.1-flash는 probe가 없어 텍스트 전용·사이드카로 그대로 둡니다. tests/providers/flash-route-image-modalities.test.ts도 command-code DeepSeek가 이제 네이티브 ["text","image"]이고 사이드카 소비자가 아니라고 단언하도록 바뀌었고, opencode-go 사이드카·콤보 교집합·한 멤버 collapse 케이스는 그대로 남습니다. types.ts/config.ts 분할 캠페인에 무효화되는 형태가 아니고, 중복 PR도 아닙니다.

라인 수준

src/providers/registry/model-seeds.ts COMMAND_CODE_IMAGE_MODELS - id를 IMAGE 목록에 넣는 순간 사이드카가 꺼집니다. probe가 틀리면 예전에 사이드카가 막아 주던 ‘이미지가 조용히 버려지는’ 실패가 다시 열립니다. 헤더의 verified-negative 경고와 같은 위험입니다.
PR 본문 probe - 증거는 기여자 서술(2.58.0 설치, api.commandcode.ai, 기존 OAuth)입니다. 원본 프록시 로그·격자 PNG·응답 전문은 PR에 첨부되지 않았고, package도 지금 tip 2.59.0과 한 칸 차이입니다.
COMMAND_CODE_TEXT_ONLY_MODELS = [] as const - 빈 배열을 남겨 메커니즘을 보존한 선택은 타당합니다. 다만 export가 비어 있으면 다음 기여자가 ‘쓰이지 않는 상수’로 오해하고 지울 수 있어, 주석이 그 역할을 계속 해야 합니다.
tests/providers/flash-route-image-modalities.test.ts - 분류 단언은 새 선언과 맞습니다. 다만 테스트는 레지스트리 테이블만 읽고 실제 CommandCode upstream을 치지 않으므로, 네이티브 주장의 진실성은 여전히 외부 probe에 달려 있습니다.
전체 스위트 35 fail 주장 - 작성자가 stash 전후 동일·환경 전용이라고 적었지만, 이 환경에서 재현을 확인하지 못했습니다. hosted CI를 게이트로 두는 편이 맞습니다.

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

  • 기여자가 서술한 2026-09-18 probe만으로 네이티브 승격을 받아들일지, 아니면 로그/격자 재현을 한 번 더 요구할지.
  • 2.58.0에서 통과한 probe를 2.59.0 dev tip에도 그대로 신뢰할지(어댑터 경로가 그 사이 바뀌지 않았는지).
  • 빈 COMMAND_CODE_TEXT_ONLY_MODELS export를 계속 둘지, 다음 텍스트 전용 경로가 생길 때까지 파일 주석만으로 충분한지.
  • #4505는 이미 CLOSED라 Closes 링크는 없습니다. 릴리스 노트에 ‘CommandCode DeepSeek V4.1 Flash now native image’ 한 줄을 넣을지.

너의 추천

CI(changes/hygiene와 flash-route-image-modalities 포함 관련 스위트)가 초록이면 merge하세요. 범위가 #4505가 남겨 둔 probe 후속과 정확히 맞고, opencode-go는 건드리지 않으며, 테스트·주석·빈 TEXT_ONLY 메커니즘 보존까지 한 덩어리로 정리된 유지보수형 레지스트리 PR입니다. types/config 분할 때문에 닫을 대상이 아닙니다. 메인테이너가 probe 원본을 직접 보고 싶다면 merge 전에 코멘트만 짧게 요청하면 됩니다.

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

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

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@xinzhihong-ship-it

Copy link
Copy Markdown
Contributor Author

Raw receipts for the probe, since the description carried only the summary.

Environment: @bitkyc08/opencodex 2.58.0 (released version; it was the dev tip at probe time on 2026-09-18), command-code provider with the account's own OAuth credential, requests over loopback POST /v1/messages for model command-code/deepseek/deepseek-v4.1-flash.

Payload: 180x180 PNG, 3x3 grid, six candidate colors per cell, every cell chosen independently at random — a blind answer matches all nine with ~(1/6)^9 ≈ 3e-7 probability. Question: name the nine colors top-to-bottom, left-to-right.

Probe A — image as a user message

  • Ground truth: 红 黑 绿 / 白 白 绿 / 白 黑 黄
  • Verbatim reply: 红、黑、绿、白、白、绿、白、黑、黄 — 9/9
  • Usage row (account label and conversation id redacted):
{"timestamp":1789714653678,"provider":"command-code","model":"deepseek/deepseek-v4.1-flash","status":200,"durationMs":2766,"usage":{"inputTokens":7853,"outputTokens":159,"cacheReadInputTokens":7296},"adapter":"command-code","sendCount":1,"recoveryKinds":[]}

Probe B — image as a tool_result (assistant tool_use + matching tool_result carrying the image block)

  • Ground truth: 白 黑 绿 / 蓝 绿 白 / 蓝 黑 白
  • Verbatim reply: 白、黑、绿、蓝、绿、白、蓝、黑、白 — 9/9
  • The first B attempt hit max_tokens mid-thinking and returned no text block; it was retried with a larger cap. Both rows, redacted:
{"timestamp":1789714931163,"provider":"command-code","model":"deepseek/deepseek-v4.1-flash","status":200,"durationMs":2747,"usage":{"inputTokens":7916,"outputTokens":300,"cacheReadInputTokens":7424},"adapter":"command-code","sendCount":1,"recoveryKinds":[]}
{"timestamp":1789714975449,"provider":"command-code","model":"deepseek/deepseek-v4.1-flash","status":200,"durationMs":2523,"usage":{"inputTokens":7916,"outputTokens":245,"cacheReadInputTokens":7680},"adapter":"command-code","sendCount":1,"recoveryKinds":[]}

No vision-sidecar call appears in either request window: the nearest luna attempt in the same log is a 429 two minutes before probe A and is unrelated to both. recoveryKinds is empty throughout, and each request was a single sendCount: 1 attempt.

Version note: the probe ran on released 2.58.0. The claim concerns the upstream gateway accepting pixels end-to-end; the command-code adapter's image path is not version-gated, but happy to re-run against a tip build if a fresh receipt is preferred.

Reproduction script (python3, stdlib only — regenerates a fresh random grid per run)
import zlib, struct, base64, json, random

COLORS = {"红": (255,0,0), "绿": (0,170,0), "蓝": (0,0,255),
          "黄": (255,255,0), "白": (255,255,255), "黑": (0,0,0)}
KEYS = list(COLORS)
grid = [[random.choice(KEYS) for _ in range(3)] for _ in range(3)]

CELL = 60
W = H = CELL * 3
rows = []
for y in range(H):
    row = bytearray([0])  # PNG filter: None
    for x in range(W):
        row += bytes(COLORS[grid[y // CELL][x // CELL]])
    rows.append(bytes(row))
raw = b"".join(rows)

def chunk(tag, data):
    return struct.pack(">I", len(data)) + tag + data + struct.pack(">I", zlib.crc32(tag + data) & 0xFFFFFFFF)

png = (b"\x89PNG\r\n\x1a\n"
       + chunk(b"IHDR", struct.pack(">IIBBBBB", W, H, 8, 2, 0, 0, 0))
       + chunk(b"IDAT", zlib.compress(raw, 9))
       + chunk(b"IEND", b""))

print("ground truth:")
for r in grid:
    print("  " + " ".join(r))

req = {
    "model": "command-code/deepseek/deepseek-v4.1-flash",
    "max_tokens": 300,
    "messages": [{"role": "user", "content": [
        {"type": "image", "source": {"type": "base64", "media_type": "image/png",
                                     "data": base64.b64encode(png).decode()}},
        {"type": "text", "text": "这是一张 3x3 九宫格图片,每格是一个纯色方块。请按从上到下、每行从左到右的顺序,说出九格各自的颜色(用中文,只列颜色即可)。"},
    ]}],
}
json.dump(req, open("/tmp/probe_req.json", "w"))

# POST /tmp/probe_req.json to the running proxy's /v1/messages with the loopback credential.
# Probe B uses the same image block nested in a tool_result instead of the user message.

@github-actions

github-actions Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • review readiness checklist open (0/4 boxes ticked).

What to do

  • Tick all four boxes in the PR description once you're done (currently 0/4).

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.

0/4 boxes ticked.

Automatic draft conversion failed. Please convert this pull request to a draft manually until every box above is ticked.

@github-actions
github-actions Bot marked this pull request as draft September 18, 2026 07:56
@lidge-jun

Copy link
Copy Markdown
Owner

Merging. The probe is what this needed and it is recorded where the next reader will find it.

#4505 asked for upstream evidence before promoting the id, and the entry now carries it: a 3x3 random-colour grid read 9/9 correct on both the user-message and the tool_result path, with request logs showing no vision-sidecar call in either window. That is the difference between a declaration and a guess, and it is why the sibling deepseek/deepseek-v4-flash route correctly stays verified-negative.

Emptying COMMAND_CODE_TEXT_ONLY_MODELS rather than deleting it is the right call. The mechanism is what lets a route advertise sidecar-backed image input without claiming native vision, and the next route that measures text-only will want it; an empty list with a dated note explains itself, while a deleted one would have to be rediscovered.

@lidge-jun
lidge-jun marked this pull request as ready for review September 18, 2026 09:53
@lidge-jun
lidge-jun merged commit 1be5cb3 into lidge-jun:dev Sep 18, 2026
30 of 32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants