Skip to content

fix(devin): preserve catalog supports_images as a tri-state - #4547

Merged
lidge-jun merged 1 commit into
devfrom
codex/260914-l2-devin-catalog-supports-images
Sep 13, 2026
Merged

fix(devin): preserve catalog supports_images as a tri-state#4547
lidge-jun merged 1 commit into
devfrom
codex/260914-l2-devin-catalog-supports-images

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Summary

Verification

  • Local product suite, typecheck, build, and install were NOT RUN (repository policy for this delivery round). The only proof is hosted Cross-platform CI at the exact head SHA 7f94c524bd8ac5cc62f06b4551c7e38a6ca327d1: run 34775751844 (pull_request event, the run attached to this PR's checks). An earlier explicit workflow_dispatch run (34775719256) at the same SHA was a duplicate of this run and was cancelled as redundant.
  • Debugging-only, not proof: bun run structure:check passed locally. The focused adapter test file could not run locally because dependencies are not installed in this worktree (install is out of scope for this round).
  • No GUI change; no screenshot.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed. (structure/adapters/registry.md records the pre-flight contract; no user-facing release note — the flag is not yet propagated to the client catalog.)
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults. (Not security-sensitive in the MAINTAINERS.md sense: no auth, credential, workflow, or release surface. Considered: no secrets, no auth changes; the unsafe-default risk of collapsing unknown to text-only is exactly what the tri-state avoids.)

parseCatalogBuffer had arms for ClientModelConfig fields 1, 4, 18 and 22
and no default, so field 5 (supports_images) was dropped by omission.
Carry it on ModelCatalogEntry as an optional boolean: a present true
asserts text+image support, a present false asserts text-only, and an
omitted field stays unknown. It deliberately does not copy the disabled
pattern, which defaults to false — collapsing unknown into text-only was
the #1796 regression, and antigravity-models.ts already implements the
same tri-state for its discovered catalog.

The header schema comment gains the #5 row and the #18 row it never
listed, and its verification claim now says which fields came from the
bundled extension.js, which from a live catalog dump, and which from the
public WindsurfAPI documentation. The owning structure doc records the
catalog pre-flight contract. Propagation of the flag to the client
catalog is a separate change.
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner September 13, 2026 18:48
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 13, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-13T18:52:12.762188Z 7f94c52 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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: 2f3d093e-8ede-42c9-8b72-ebc1dc16d1a3

📥 Commits

Reviewing files that changed from the base of the PR and between 10d61fc and 7f94c52.

📒 Files selected for processing (3)
  • src/adapters/devin/cloud-direct/catalog.ts
  • structure/adapters/registry.md
  • tests/providers/devin-adapter.test.ts

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


📝 Walkthrough

Walkthrough

The Devin cloud-direct catalog now parses ClientModelConfig field #5 into optional tri-state supportsImages. Documentation describes the field and catalog pre-flight. Tests cover true, false, and undefined states.

Changes

Devin catalog image support

Layer / File(s) Summary
Catalog contract and parsing
src/adapters/devin/cloud-direct/catalog.ts
ModelCatalogEntry now exposes optional supportsImages. parseCatalogBuffer parses field #5 and omits the property when the field is absent. The schema comments describe fields #5 and #18.
Catalog documentation and tests
structure/adapters/registry.md, tests/providers/devin-adapter.test.ts
The registry documentation describes catalog pre-flight field handling. Tests verify encoded 1, encoded 0, and an omitted field.

Priority: ⬇️ Low

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

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 7f94c

This narrowly scoped metadata change has no confirmed impact on client-visible routing or model capabilities.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: preserving Devin catalog supports_images as a tri-state value. It matches the parser, documentation, and test updates.
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. (1 skipped: 1 …
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/260914-l2-devin-catalog-supports-images

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 Author

리뷰 · 우선순위 58 / 80

이 PR은 Devin cloud-direct 카탈로그 파서 src/adapters/devin/cloud-direct/catalog.ts가 Cognition GetCascadeModelConfigs 응답의 ClientModelConfig 필드 #5 (supports_images) 를 읽지 않고 버리던 구멍을 막습니다. 지금 로컬 dev HEAD는 10d61fc2b이고, 방금 올라온 줄은 #4511입니다. 그 패치는 네이티브 행의 vision 자격을 운영자 modelCapabilities.inputModalities(텍스트 전용 선언)까지 존중하게 바꿨습니다. 이번 PR은 그 소비자 쪽이 아니라 공급자(어댑터 카탈로그) 쪽 증거를 살리는 작업입니다. base는 dev입니다.

왜 중요하냐면, 이 모듈의 원래 목적은 이슈 #14 계열입니다. 계정 티어에 없는 model_uid로 채팅하면 클라우드가 권한 거부를 내부 오류처럼 돌려주니, 채팅 전에 카탈로그 disabled(#4)로 미리 거르는 겁니다. 그 파서는 이미 #4와 #18(max_input_tokenscontextWindow), #22(model_uid)만 읽었고 default 분기가 없어서 모르는 필드는 조용히 사라집니다. 그래서 #5가 응답에 있어도 바이트만 스킵되고 ModelCatalogEntry에는 흔적이 없었습니다. 이 PR은 #5 varint 암을 추가하고, 값을 선택적 boolean 삼상태로 싣습니다. 있음=true면 텍스트+이미지 주장, 있음=false면 텍스트 전용 주장, 필드 자체가 없으면 undefined(모름)입니다.

삼상태를 고른 이유는 레포 안에서 이미 검증된 교훈입니다. disabled는 없으면 false로 두는 게 맞지만, 이미지 지원을 그렇게 접으면 “한 번도 주장되지 않음”이 “텍스트 전용”으로 굳어집니다. 그게 #1796 회귀(라우팅이 카탈로그 행을 자신 있는 image: false로 읽음)였고, src/providers/antigravity-models.ts는 이미 supportsImages === true|falseinputModalities로 옮기고 없으면 키 자체를 빼는 패턴을 씁니다. 이번 패치는 그 선례를 Devin 카탈로그 엔트리에 그대로 맞춥니다. PR 본문도 솔직합니다. 지금 레이어만 바꾸면 클라이언트에 보이는 동작은 없습니다. 플래그는 파싱된 엔트리에서만 보이고, 클라이언트 카탈로그·비전 라우팅으로의 전파는 후속입니다.

헤더 스키마 주석도 같이 고칩니다. 예전에는 #1/#4/#22만 적혀 있었고 #18은 코드에서만 파싱됐습니다. 이번엔 #5와 #18을 주석에 올리고, 검증 출처를 필드별로 나눕니다(#1/#4/#22는 번들 extension.js, #18은 라이브 카탈로그 덤프, #5는 공개 WindsurfAPI ClientModelConfig 문서 교차확인). structure/adapters/registry.md에는 카탈로그 pre-flight 계약(#4/#18/#5)을 한 줄로 남깁니다. AGENTS.md 구조 의무에 맞는 기록입니다. 테스트는 tests/providers/devin-adapter.test.ts에 픽스처 세 개입니다. varint 1 → true, varint 0 → toBe(false)(생략이 아님), 필드 없음 → 엔트리는 있고 supportsImagestoBeUndefined(). toBeFalsy를 피한 점이 핵심입니다. 로컬 product/typecheck/build는 이번 라운드 정책상 안 돌렸고, 증거는 호스트 CI run 34775719256(그리고 PR 체크 잡들)입니다. 리뷰 시점 기준 Cross-platform/changes 등은 아직 pending이었습니다.

types.ts/config.ts 분할 캠페인과는 겹치지 않습니다. 닫을 중복도 아닙니다. #4501/#4511은 네이티브 행 eligibility 소비자 쪽이고, 이 PR은 Devin protobuf 파서 공급자 쪽이라 서로 대체 관계가 아닙니다.

src/adapters/devin/cloud-direct/catalog.ts 필드 #5 암 - 구현 자체는 #4와 같은 varint 0/1 패턴이라 맞습니다. 문제는 “파서에만 남고 끝나는” 상태입니다. src/adapters/devin/live-models.tsfetchDevinUsableModels는 지금도 disabledcontextWindow만 읽고 supportsImages는 무시합니다. PR이 약속한 범위 안이지만, 후속 없이 머지만 하면 카탈로그 증거가 다시 한 단계 위에서 증발합니다.

ModelCatalogEntry.supportsImages - 선택적 스프레드(!== undefined일 때만 키 삽입)는 #1796 교훈과 맞습니다. 다만 후속에서 effort 접미사 UID를 base로 접을 때(이미 contextWindowMath.min 규칙을 씀) true/false/unknown 형제 행을 어떻게 합칠지 규칙이 없습니다. 지금 PR 범위 밖이지만 전파 PR에서 반드시 정해야 합니다.

스키마 주석의 #5 출처 - #18은 라이브 덤프인데 #5는 공개 WindsurfAPI 문서 교차확인입니다. Cognition GetCascadeModelConfigs와 Windsurf ClientModelConfig가 같은 protobuf 가문이어도 필드 번호 드리프트 위험이 있습니다. 라이브 카탈로그에서 #5 바이트가 실제로 오는지 한 번만 더 확인하면 안심이 큽니다.

CI - 로컬 스위트/설치를 안 돌린 라운드라, 머지 판단의 유일한 자동 증거는 호스트 CI입니다. 리뷰 작성 시점엔 checks가 pending이었습니다. 그린 나오기 전에 랜딩하지 마세요.

structure/adapters/registry.md - pre-flight 문장은 정확합니다. “클라이언트 카탈로그까지 전파됨”처럼 읽히지 않게, 파서 보존 단계라는 점이 드러나 있어 과장은 없습니다.

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

  • Fix stale Codex autostart shim repair #5 필드 번호를 라이브 Cognition 카탈로그 덤프로 한 번 더 확인할지, 공개 WindsurfAPI 교차확인만으로 충분한지
  • 이 PR을 파서-only로 바로 랜딩할지, live-models.ts → 클라이언트 카탈로그 → vision eligibility까지 묶은 후속과 한 트레인으로 갈지
  • 후속 전파 시 effort-접미사 형제 UID의 supportsImages 충돌 규칙(하나라도 true / 모두 동의 / unknown 우선 등)
  • CI(명시 dispatch run + PR checks) 그린을 머지 게이트로 고정할지

너의 추천
CI(changes/hygiene 포함) 그린 확인 뒤 이 PR은 그대로 머지하세요. 범위가 작고 #1796 삼상태 선례와 일치하며 #4511 소비자 쪽과도 충돌하지 않습니다. 머지 직후 follow-up으로 fetchDevinUsableModels(및 클라이언트 카탈로그)에 같은 삼상태를 전파하되, absent를 text-only로 접지 말고 antigravity와 동일한 === true|false만 modalities로 옮기는 형태를 유지하세요. 가능하면 머지 전에 라이브 카탈로그 덤프로 필드 #5 존재만 한 번 눈으로 확인하면 더 안전합니다.

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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f94c524bd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +136 to +139
} else if (sf.num === 5 && sf.wire === 0) {
// #5 = supportsImages (bool, varint 0/1). Absent stays unknown — see
// ModelCatalogEntry; do not default it like disabled.
supportsImages = sf.value === 1n;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Update every mapped adapter document

This changes the shared src/adapters/ catalog contract, but inspection of the commit shows that only structure/adapters/registry.md was updated; the other documents mapped to src/adapters/ in structure/INDEX.md—including runtime.md, the three transport documents, data-planes/inbound-compat.md, providers/cursor.md, and providers/chat-compat.md—remain unchanged. Update every mapped document in this change, or correct the manifest ownership if those documents should not own this area, so the repository's source-to-document contract does not drift.

AGENTS.md reference: src/AGENTS.md:L11-L11

Useful? React with 👍 / 👎.

@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

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

Copy link
Copy Markdown
Owner Author

Integrating through the maintainer self-integration path in MAINTAINERS.md and recording that choice here.

Exact-head evidence: Cross-platform CI run 34775751844 completed success at the current head. Local product suite, typecheck, build and install NOT RUN; a fresh lane worktree has no node_modules, so hosted CI at that SHA is the only evidence that could exist.

On the change: parseCatalogBuffer had arms for protobuf fields 1, 4, 18 and 22 and no default, so ClientModelConfig field 5 was dropped by omission and every Devin model arrived with no image-support signal at all. The flag is now carried as an optional tri-state. Absence stays unknown rather than collapsing to false, which is the #1796 precedent and the same shape Antigravity already uses; copying the disabled pattern here would have asserted text-only for every model the vendor simply did not describe.

This layer changes nothing client-visible on purpose. Propagation to the advertised catalog and the operator-override precedence are the round-2 layer and are not in this diff.

@lidge-jun
lidge-jun merged commit 6329f30 into dev Sep 13, 2026
42 of 61 checks passed
@lidge-jun
lidge-jun deleted the codex/260914-l2-devin-catalog-supports-images branch September 13, 2026 19:34
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.

1 participant