Skip to content

Commit 46a435d

Browse files
feat: take vision flags from Command Code CLI inputModalities
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 5f334e0 commit 46a435d

9 files changed

Lines changed: 260 additions & 188 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313

1414
### Added
1515

16-
- Catalog models include vision vs text-only metadata (`attachment` / `modalities`) copied from models.dev; unmatched models default to text-only.
16+
- Catalog models include vision vs text-only from the Command Code CLI `inputModalities` field on every SKU. models.dev only adds extra inputs (video/audio/pdf) on matches.
1717

1818
## [0.6.1] - 2026-08-28
1919

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ This package is based on **[FanFan4204/opencode-commandcode-provider](https://gi
1919
- Bundled `models.json` is the default runtime catalog (no local CLI scrape).
2020
- CLI cost extraction can fail (as on `command-code@1.38.x`) without dropping models.
2121
- Official docs fill missing costs; remaining paid gaps use [models.dev](https://models.dev) as a reference. Command Code free SKUs stay `$0`.
22-
- Vision vs text-only (`attachment` / `modalities`) is copied from models.dev during catalog sync. Unmatched models are text-only.
22+
- Vision vs text-only comes from the Command Code CLI catalog (`inputModalities` on every SKU). [models.dev](https://models.dev) only adds extra inputs (video/audio/pdf) when it matches.
2323
- Reasoning effort **variants** on models that declare `reasoningEfforts`.
2424
- Quiet OpenCode startup (diagnostics go to `startup.json`, not stdout).
2525

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Spec: Catalog modalities from models.dev
1+
# Spec: Catalog modalities from Command Code CLI
22

33
Status: approved (2026-08-28)
44
**Branch:** `feature/2026-08-28-catalog-modalities`
@@ -7,56 +7,54 @@ Parent: [docs/2026-08-28-ci-catalog/spec.md](../2026-08-28-ci-catalog/spec.md)
77

88
## Goals
99

10-
- G1: Every bundled catalog model carries OpenCode `attachment` and `modalities` copied from [models.dev](https://models.dev).
11-
- G2: Unmatched models default to text-only (no vision guessing, no frozen allowlist).
12-
- G3: Cost waterfall stays independent; modalities apply to all matching models including free SKUs.
10+
- G1: Every Command Code SKU in the bundled catalog carries OpenCode `attachment` and `modalities` from the CLI catalog `inputModalities` field (same extract as ids/reasoning).
11+
- G2: models.dev only **enriches** extra input types (`video` / `audio` / `pdf`) on matches. It never overwrites CLI vision/text-only and never invents text-only for a SKU the CLI already classified.
12+
- G3: Cost waterfall stays independent.
1313

1414
## Locked (do not reopen)
1515

16-
- Source of truth is models.dev `attachment` + `modalities` (same fetch already used for costs). No human allowlist. No guessing vision.
17-
- Cost waterfall stays independent. Modalities apply to **all** matching models, including free SKUs and models that already have CLI/docs prices.
18-
- Unmatched models default to text-only: `attachment: false`, `modalities: { input: ["text"], output: ["text"] }`.
19-
- Runtime still does not fetch models.dev. Sync writes the fields into `models.json`; `generateOpencodeModels` emits them (and the text-only default if a field is missing).
20-
- Do not overwrite CLI `limit`, `reasoning`, or `tool_call` from models.dev.
21-
- Do not inject capability text into the session prompt. Asking the chat model “what can you do?” is out of scope.
16+
- Command Code CLI catalog is the source of truth for native vision vs text-only. The public GitHub repo is a stub; the field lives on every model object in the npm `command-code` bundle as `inputModalities: ["text"]` or `["text","image"]`.
17+
- Provider API `GET /provider/v1/models` has `context_length` only — no vision flags. Official docs Capabilities column is icons, not structured data.
18+
- models.dev may add extra modality strings; it must not flip a CLI text-only model to vision or wipe CLI vision on unmatched ids.
19+
- Last-resort text-only applies only when a model has **no** CLI `inputModalities` and no models.dev match (e.g. hardcoded extras).
20+
- Runtime still does not fetch models.dev. Sync writes the fields into `models.json`.
21+
- Do not overwrite CLI `reasoning` / `reasoningEfforts` from models.dev.
22+
- Do not inject capability text into the session prompt.
2223

2324
## Context
2425

25-
`generateOpencodeModels` currently emits `id`, `name`, `reasoning`, `tool_call`, `cost`, `limit`, and optional `reasoningEfforts`/`variants`. OpenCode uses `attachment` and `modalities.input` for vision. Hy4 Preview (`tencent/hy4-preview`) is text-only on models.dev with a 1,048,576 context window already present on `limit`; the model itself does not read that metadata.
26+
`extractModelCatalog` already evaluates full CLI model objects. `buildModelEntry` previously dropped `inputModalities` and `maxOutputTokens`. Hy4 Preview is `["text"]` in the CLI catalog (not a missing match). Gemini 3.5 Flash is `["text","image"]`.
2627

2728
## Non-goals
2829

29-
- Session/system-prompt injection of context window or vision flags
30-
- Filling `limit` from models.dev
31-
- Local OpenCode overlay `commandcode-modalities.ts` (becomes redundant after this ships; not deleted in this repo)
30+
- Session/system-prompt injection
31+
- Local OpenCode overlay `commandcode-modalities.ts` (redundant after this ships)
3232
- Changing hybrid Provider API transport
33+
- Parsing the HTML Capabilities column on commandcode.ai docs
3334

3435
## Architecture
3536

3637
```mermaid
3738
flowchart TD
38-
sync["bun run sync"] --> fetch[Fetch models.dev api.json]
39-
fetch --> costs[applyModelsDevCosts skip priced/free]
40-
fetch --> mods[applyModelsDevModalities all models]
41-
mods --> unmatched[No match: text-only default]
42-
costs --> json[models.json]
43-
unmatched --> json
39+
sync["bun run sync"] --> cli[Extract CLI catalog including inputModalities]
40+
cli --> map["buildModelEntry: attachment + modalities per SKU"]
41+
map --> fetch[Fetch models.dev]
42+
fetch --> enrich[Union extra inputs on matches only]
43+
enrich --> json[models.json]
4444
json --> emit[generateOpencodeModels]
45-
emit --> oc["OpenCode attachment + modalities"]
4645
```
4746

48-
Matching reuses the existing models.dev index: exact id, then last path segment, then display name (case-insensitive). Copy `modalities` arrays as-is (Gemini may include `video` / `audio` / `pdf`). `attachment` comes from models.dev when present, otherwise `modalities.input` includes `"image"`.
49-
5047
## Acceptance criteria
5148

52-
- CA-01: `parseModelsDev` retains `attachment` and `modalities` on rows that already have costs.
53-
- CA-02: `applyModelsDevModalities` sets Gemini-style vision on a matching catalog id and text-only on Hy4 Preview / unmatched ids.
54-
- CA-03: Free SKUs and CLI-priced models still receive modalities (not skipped the way costs are).
55-
- CA-04: `generateOpencodeModels` always emits `attachment` and `modalities`; missing fields become text-only.
56-
- CA-05: `bun run sync` applies modalities from the same models.dev JSON used for costs; if that fetch fails, every model still gets the text-only default before write.
57-
- CA-06: README states that vision/text-only comes from models.dev.
49+
- CA-01: `buildModelEntry` maps CLI `inputModalities` including `"image"` to `attachment: true` and maps `["text"]` to text-only, including Hy4 Preview.
50+
- CA-02: `loadCatalogFromBundle` preserves those fields from a minified CLI-shaped catalog.
51+
- CA-03: `applyModelsDevModalities` keeps CLI vision on ids models.dev does not list.
52+
- CA-04: models.dev may append extra inputs (e.g. Gemini `video`/`audio`/`pdf`) without removing CLI `text`/`image`.
53+
- CA-05: `generateOpencodeModels` always emits `attachment` and `modalities`.
54+
- CA-06: README states vision/text-only comes from the CLI catalog.
5855

5956
## Decisions
6057

61-
- D-01: Conservative default is text-only, not “omit the field and let OpenCode guess”.
58+
- D-01: CLI `inputModalities` wins over models.dev for native vision vs text-only.
6259
- D-02: Extra modality strings from models.dev are copied, not filtered to `text`/`image`.
60+
- D-03: `maxOutputTokens` from the CLI sets `limit.output` when present.

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"schemaVersion": 1,
3-
"generatedAt": "2026-08-28T21:04:48.971Z",
3+
"generatedAt": "2026-08-28T21:14:42.165Z",
44
"pluginVersion": "0.6.1",
55
"commandCodeVersion": "1.38.1",
66
"commandCodeTarball": "https://registry.npmjs.org/command-code/-/command-code-1.38.1.tgz",

0 commit comments

Comments
 (0)