opencode-cmd-provider 1.6.4 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,62 @@
1
+ ## 1.7.0 - 2026-09-06
2
+
3
+ ### Model catalog: models.md-primary with enrichment that never blocks shipping
4
+
5
+ The Model catalog's membership authority flipped: the npm `command-code`
6
+ package's bundled models.md table is now the sole authority — every row
7
+ ships in the Snapshot on the next refresh, even when the provider listing
8
+ API lags (day-1 models like `gpt-6-astra` appear immediately). The listing
9
+ API is demoted to a pure divergence reporter (annotate-only, zero gating
10
+ power, zero field writes), and every other source — RSC slug records, the
11
+ CLI bundle, the Command Code models page — is enrichment that fills gaps
12
+ but never decides membership, never wins a ship-bar field, and never gates
13
+ the refresh (see ADR-0008 and the rewritten glossary in `CONTEXT.md`).
14
+
15
+ - **Ship-bar parsing** — `scripts/parse-facts.mjs` converts coarse Context
16
+ tokens through a pinned decimal table; a missing Context cell ships as
17
+ `null` (pending, resolved by the fallback ladder), a missing price cell
18
+ ships cost-less (never zero-filled, missing never reads as free), and
19
+ unparseable cells fail loudly. `facts.ts` is now a re-export shim over
20
+ the snapshot rows, keeping the consumer contract stable.
21
+ - **Enrichment fallback ladders** — context resolves models.md → RSC
22
+ `contextWindow` → CLI bundle → carried-forward last-known-good (each
23
+ step annotated, provenance recorded on the row); costs resolve models
24
+ page index → model detail page → RSC rates (never carried forward, so a
25
+ model going free is never billed at its old rate); modalities fall back
26
+ CLI bundle → models page Caps Vision bit → text-only. Total absence of
27
+ context or cost is a loud failure (unshippable ship-bar row) — one of
28
+ the two surviving loud failure classes.
29
+ - **Sparse classification** — reasoning derives any-true-wins across
30
+ models.md efforts, the RSC `reasoning` flag, and the models page Caps
31
+ Reasoning bit; models with no evidence anywhere ship in a visible
32
+ pending bucket and behave as non-reasoning until evidence arrives.
33
+ - **Models page index** — `scripts/parse-models-page.mjs` parses display
34
+ rates, Context strings, and Caps bits from the Command Code models page
35
+ (shape-strict rows, pinned Caps labels, footnote/banded-pricing notes),
36
+ with a pinned 68-entry slug-to-id join map and a re-captured
37
+ `tests/fixtures/models-page.html`.
38
+ - **Richer refresh diffs** — a package-table row removal prunes the
39
+ Snapshot immediately with a loud Removed-models section; the Model
40
+ catalog diff gains five enrichment subsections (pending enrichment per
41
+ model, carried-forward context, cost-fallback provenance, API
42
+ divergence, banded-pricing notes); identical catalogs still
43
+ short-circuit to No changes.
44
+ - **Catalog refresh** — snapshot refreshed to `command-code@1.49.1` (68
45
+ models); classification 68 entries, deals 71 entries, coverage gate OK.
46
+ - **Fixes** — facts rows filtered to snapshot ids (an ahead-of-API
47
+ models.md row broke the cron's stale-entry check); RSC fixture
48
+ assertions tolerate docs-ahead-of-API records.
49
+
50
+ ### Follow-ups
51
+
52
+ - Open issues carried forward: #136 (reasoning text rendered as normal
53
+ output), #102 (TUI/server init via npm package name), #90 (expired-deal
54
+ filtering).
55
+
56
+ ## 1.6.5 - 2026-09-04
57
+
58
+ Automated catalog refresh.
59
+
1
60
  ## 1.6.4 - 2026-09-03
2
61
 
3
62
  ### Model catalog
package/README.md CHANGED
@@ -13,12 +13,17 @@ A provider and plugin for [OpenCode](https://opencode.ai) that connects to the [
13
13
  opencode plugin opencode-cmd-provider
14
14
  ```
15
15
 
16
- Update an existing install:
16
+ Update an existing install — OpenCode caches the plugin package and reuses it
17
+ on every startup without checking for a newer version, so updating means
18
+ deleting the cache:
17
19
 
18
20
  ```sh
19
- opencode plugin opencode-cmd-provider --force
21
+ rm -rf ~/.cache/opencode/packages/opencode-cmd-provider*
20
22
  ```
21
23
 
24
+ Restart OpenCode afterwards. The plugin is re-downloaded, so that first launch
25
+ takes a little longer than usual; subsequent startups are fast again.
26
+
22
27
  Install globally (available in every project):
23
28
 
24
29
  ```sh
@@ -117,7 +122,9 @@ Delivery is zero-step: the package exports both a `server` and a `tui` target
117
122
  opencode-cmd-provider` writes both `opencode.json(c)` and `tui.json` from one
118
123
  spec. The sidebar is a TUI plugin loaded from `tui.json` — which is why
119
124
  installs made before the `./tui` export only wrote the server target and never
120
- showed a sidebar. Re-run with `--force` to add `tui.json`.
125
+ showed a sidebar. Re-run `opencode plugin opencode-cmd-provider --force` to add
126
+ `tui.json` (this only rewrites the config entry — see
127
+ [Update and remove](#update-and-remove) for refreshing the cached package).
121
128
 
122
129
  When the Deals catalog is empty (the upstream fetch failed or the RSC shape
123
130
  changed), the feature degrades visibly rather than silently: the sidebar shows
@@ -135,7 +142,9 @@ paid model (e.g. the MiniMax M3 free tier) get a `(free)` suffix —
135
142
  `[CMD] MiniMax M3 (free)` — so the two are distinguishable in the model
136
143
  picker. The suffix is derived from the bundled pricing table: a model is
137
144
  labeled free only when the catalog carries an explicit zero-cost entry. Model
138
- availability changes when the package is updated. You can still declare your
145
+ availability changes when the package is updated but note that OpenCode's
146
+ plugin cache can hold a stale copy after a release if new models don't appear
147
+ (see [Update and remove](#update-and-remove)). You can still declare your
139
148
  own `provider.commandcode` entry; your declarations always win and the
140
149
  snapshot fills in only what's missing (`whitelist`/`blacklist` on a declared
141
150
  entry filter the auto-registered models too).
@@ -184,7 +193,9 @@ Actions cron
184
193
  (`.github/workflows/catalog-refresh.yml`, 06:00 UTC, also manually
185
194
  triggerable via `workflow_dispatch`) runs the same pipeline: when upstream
186
195
  moved it opens a `chore: catalog refresh` PR whose body is the human-readable
187
- diff from `scripts/diff-catalog.mjs` — model catalog, reasoning
196
+ diff from `scripts/diff-catalog.mjs` — model catalog (change table plus
197
+ removed-models, pending-enrichment, carried-forward-context, cost-fallback,
198
+ API-divergence, and banded-pricing subsections), reasoning
188
199
  classification (flips, new reasoning models, retirements, active overrides),
189
200
  and deals sections; when nothing meaningful drifted it exits silently (a
190
201
  run whose only change is the refreshed-date stamps opens no PR).
@@ -232,7 +243,37 @@ Models missing from that table display zero cost in OpenCode. This does **not**
232
243
 
233
244
  ## Update and remove
234
245
 
235
- Update the installed package, or remove it from the `plugin` array in your `opencode.json` (the auto-registered `provider.commandcode` entry is injected by the plugin, so there is no config block to remove). The npm package is cached under OpenCode's plugin cache (`~/.cache/opencode/packages/`); remove the cached directory to fully uninstall.
246
+ ### Updating
247
+
248
+ OpenCode caches the plugin package (`~/.cache/opencode/packages/`) and reuses
249
+ the cached copy on every startup without checking for a newer version — so a
250
+ new release won't appear until you delete the cache:
251
+
252
+ ```sh
253
+ rm -rf ~/.cache/opencode/packages/opencode-cmd-provider*
254
+ ```
255
+
256
+ Then restart OpenCode. The plugin is re-downloaded, so that first launch takes
257
+ a little longer than usual; subsequent startups are fast again. If new Command
258
+ Code models stop appearing in `/models` after a release, a stale cache entry is
259
+ the most likely cause.
260
+
261
+ - **OpenChamber users:** click **Reload OpenCode** in OpenChamber's settings
262
+ instead of restarting manually — the running OpenCode server keeps the old
263
+ plugin loaded until it is restarted.
264
+ - **No re-authentication needed.** Your API key is stored by OpenCode's
265
+ `/connect` flow in OpenCode's auth store (and mirrored to
266
+ `~/.commandcode/auth.json`), not inside the plugin package — the plugin reads
267
+ it from there (or the `COMMANDCODE_API_KEY` env var) at request time, so
268
+ deleting the plugin cache does not affect your login.
269
+
270
+ ### Removing
271
+
272
+ Remove it from the `plugin` array in your `opencode.json` (the auto-registered
273
+ `provider.commandcode` entry is injected by the plugin, so there is no config
274
+ block to remove). The npm package is cached under OpenCode's plugin cache
275
+ (`~/.cache/opencode/packages/`); remove the cached directory to fully
276
+ uninstall.
236
277
 
237
278
  ## Development
238
279
 
@@ -1,7 +1,8 @@
1
1
  export declare const CLASSIFICATION_SOURCE_URLS: ReadonlyArray<string>;
2
- export declare const CLASSIFICATION_LAST_REFRESHED = "2026-09-03";
2
+ export declare const CLASSIFICATION_LAST_REFRESHED = "2026-09-06";
3
3
  export declare const CLASSIFICATION_OVERRIDES: Readonly<Record<string, {
4
4
  capability: boolean;
5
5
  justification: string;
6
6
  }>>;
7
+ export declare const MODEL_REASONING_PENDING: ReadonlyArray<string>;
7
8
  export declare const MODEL_REASONING_CAPABILITY: Readonly<Record<string, boolean>>;
@@ -1,9 +1,14 @@
1
1
  // src/catalog/classification.ts — GENERATED by scripts/refresh-classification.mjs. Do not edit.
2
2
  //
3
- // Per-model reasoning capability, derived from the `reasoning` flag on
4
- // the Command Code docs' RSC slug records (plans/goat + plans/pro,
5
- // slug-id aliasing applied, keyed by snapshot id) — the same
6
- // snapshot-keyed records the Deals catalog consumes. Classification is
3
+ // Per-model reasoning capability, derived any-true-wins across the
4
+ // models.md efforts entries, the `reasoning` flag on the Command Code
5
+ // docs' RSC slug records (plans/goat + plans/pro, slug-id aliasing
6
+ // applied, keyed by snapshot id), and the models page Caps Reasoning
7
+ // bit (issue #132). The map is sparse: only models with evidence get an
8
+ // entry (true = any channel fires; false = checked evidence is
9
+ // all-negative). Models with NO evidence anywhere ship in
10
+ // MODEL_REASONING_PENDING — they behave as non-reasoning at runtime and
11
+ // flip with zero code when evidence arrives. Classification is
7
12
  // upstream-managed and derived, never hand-maintained; the only human
8
13
  // seam is CLASSIFICATION_OVERRIDES, whose entries each carry a written
9
14
  // justification naming the upstream disagreement (see ADR-0006).
@@ -13,11 +18,16 @@ export const CLASSIFICATION_SOURCE_URLS = [
13
18
  "https://commandcode.ai/docs/plans/goat",
14
19
  "https://commandcode.ai/docs/plans/pro",
15
20
  ];
16
- export const CLASSIFICATION_LAST_REFRESHED = "2026-09-03";
21
+ export const CLASSIFICATION_LAST_REFRESHED = "2026-09-06";
17
22
  // Active capability overrides. Empty = upstream data is truth.
18
23
  // Every entry requires a written justification naming the upstream
19
24
  // disagreement; entries are rendered into the refresh PR body.
20
25
  export const CLASSIFICATION_OVERRIDES = {};
26
+ // Snapshot models with no capability evidence anywhere (no RSC record,
27
+ // no models.md efforts, no models page Reasoning bit). They behave as
28
+ // non-reasoning and land in this bucket until evidence arrives — the
29
+ // next refresh moves them into MODEL_REASONING_CAPABILITY with zero code.
30
+ export const MODEL_REASONING_PENDING = [];
21
31
  export const MODEL_REASONING_CAPABILITY = {
22
32
  "claude-fable-5": true,
23
33
  "claude-fable-5-1": true,
@@ -44,6 +54,7 @@ export const MODEL_REASONING_CAPABILITY = {
44
54
  "gpt-5.6-luna": true,
45
55
  "gpt-5.6-sol": true,
46
56
  "gpt-5.6-terra": true,
57
+ "gpt-6-astra": true,
47
58
  "meituan/LongCat-2.0:free": true,
48
59
  "meta/muse-spark-1.1": true,
49
60
  "meta/muse-spark-1.2": true,
@@ -1,7 +1,7 @@
1
- export declare const FACTS_SOURCE_URL = "https://unpkg.com/command-code@1.46.0/dist/bundled/command-code-knowledge/reference/models.md";
2
- export declare const MODALITIES_SOURCE_URL = "https://unpkg.com/command-code@1.46.0/dist/cli.mjs";
3
- export declare const FACTS_PACKAGE_VERSION = "1.46.0";
4
- export declare const FACTS_LAST_REFRESHED = "2026-09-03";
1
+ export declare const FACTS_SOURCE_URL = "https://unpkg.com/command-code@1.49.1/dist/bundled/command-code-knowledge/reference/models.md";
2
+ export declare const MODALITIES_SOURCE_URL = "https://unpkg.com/command-code@1.49.1/dist/cli.mjs";
3
+ export declare const FACTS_PACKAGE_VERSION = "1.49.1";
4
+ export declare const FACTS_LAST_REFRESHED = "2026-09-06";
5
5
  export declare const MODEL_EFFORTS: Readonly<Record<string, readonly string[]>>;
6
6
  export declare const MODEL_COSTS: Readonly<Record<string, {
7
7
  input: number;
@@ -1,13 +1,14 @@
1
1
  // src/catalog/facts.ts — GENERATED by scripts/refresh-snapshot.mjs. Do not edit.
2
2
  //
3
- // Capability facts (reasoning efforts + per-1M-token rates) parsed from the
4
- // command-code npm package's bundled model catalog (models.md), plus input
5
- // modalities parsed from its CLI bundle (dist/cli.mjs). Regenerate
6
- // with `npm run refresh:snapshot`.
7
- export const FACTS_SOURCE_URL = "https://unpkg.com/command-code@1.46.0/dist/bundled/command-code-knowledge/reference/models.md";
8
- export const MODALITIES_SOURCE_URL = "https://unpkg.com/command-code@1.46.0/dist/cli.mjs";
9
- export const FACTS_PACKAGE_VERSION = "1.46.0";
10
- export const FACTS_LAST_REFRESHED = "2026-09-03";
3
+ // Capability facts derived from the models.md-primary Snapshot rows in
4
+ // src/catalog/snapshot.ts (issue #130): reasoning efforts + rates parse
5
+ // from the package table (never from the listing API). Input modalities
6
+ // parse from the CLI bundle (dist/cli.mjs). Regenerate with
7
+ // `npm run refresh:snapshot`.
8
+ export const FACTS_SOURCE_URL = "https://unpkg.com/command-code@1.49.1/dist/bundled/command-code-knowledge/reference/models.md";
9
+ export const MODALITIES_SOURCE_URL = "https://unpkg.com/command-code@1.49.1/dist/cli.mjs";
10
+ export const FACTS_PACKAGE_VERSION = "1.49.1";
11
+ export const FACTS_LAST_REFRESHED = "2026-09-06";
11
12
  export const MODEL_EFFORTS = {
12
13
  "deepseek/deepseek-v4-pro": ["high", "max"],
13
14
  "deepseek/deepseek-v4-flash": ["high", "max"],
@@ -29,6 +30,7 @@ export const MODEL_EFFORTS = {
29
30
  "claude-opus-5": ["low", "medium", "high", "xhigh", "max"],
30
31
  "claude-opus-4-8": ["low", "medium", "high", "xhigh", "max"],
31
32
  "claude-opus-4-7": ["low", "medium", "high", "xhigh", "max"],
33
+ "gpt-6-astra": ["low", "medium", "high", "xhigh", "max"],
32
34
  "gpt-5.6-sol": ["low", "medium", "high", "xhigh", "max"],
33
35
  "gpt-5.6-terra": ["low", "medium", "high", "xhigh", "max"],
34
36
  "gpt-5.6-luna": ["low", "medium", "high", "xhigh", "max"],
@@ -46,7 +48,7 @@ export const MODEL_EFFORTS = {
46
48
  "meta/muse-spark-1.1": ["low", "medium", "high", "xhigh"],
47
49
  "meta/muse-spark-1.2": ["low", "medium", "high", "xhigh"],
48
50
  "meta/muse-spark-1.2-contributor": ["low", "medium", "high", "xhigh"],
49
- "meta/muse-spark-1.3": ["low", "medium", "high", "xhigh"],
51
+ "meta/muse-spark-1.3": ["low", "medium", "high", "xhigh", "max"],
50
52
  "meta/muse-spark-1.3-contributor": ["low", "medium", "high", "xhigh"],
51
53
  "xai/grok-4.5": ["low", "medium", "high"],
52
54
  "xai/grok-4.6": ["low", "medium", "high", "xhigh"],
@@ -98,6 +100,7 @@ export const MODEL_COSTS = {
98
100
  "claude-opus-4-8": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
99
101
  "claude-opus-4-7": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
100
102
  "claude-haiku-4-5-20251001": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 },
103
+ "gpt-6-astra": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 },
101
104
  "gpt-5.6-sol": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 6.25 },
102
105
  "gpt-5.6-terra": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 },
103
106
  "gpt-5.6-luna": { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 },
@@ -151,6 +154,7 @@ export const MODEL_INPUT_MODALITIES = {
151
154
  "gpt-5.6-luna": ["text", "image"],
152
155
  "gpt-5.6-sol": ["text", "image"],
153
156
  "gpt-5.6-terra": ["text", "image"],
157
+ "gpt-6-astra": ["text", "image"],
154
158
  "meta/muse-spark-1.1": ["text", "image"],
155
159
  "meta/muse-spark-1.2": ["text", "image"],
156
160
  "meta/muse-spark-1.2-contributor": ["text", "image"],
@@ -166,6 +170,7 @@ export const MODEL_INPUT_MODALITIES = {
166
170
  "thinkingmachines/inkling": ["text", "image"],
167
171
  "thinkingmachines/inkling-small": ["text", "image"],
168
172
  "xai/grok-4.5": ["text", "image"],
173
+ "xai/grok-4.6": ["text", "image"],
169
174
  "xiaomi/mimo-v2.5": ["text", "image"],
170
175
  "z-ai/glm-5.3-flash": ["text", "image"],
171
176
  };
@@ -1,6 +1,17 @@
1
1
  export interface CatalogModel {
2
2
  readonly id: string;
3
3
  readonly name: string;
4
- readonly contextLength: number;
4
+ readonly contextLength: number | null;
5
+ /** "models.md" when the package cell parsed; else the ladder step that resolved it. */
6
+ readonly contextSource: "models.md" | "rsc" | "cli" | "carried-forward";
7
+ readonly efforts: readonly string[] | null;
8
+ readonly cost: {
9
+ readonly input: number;
10
+ readonly output: number;
11
+ readonly cacheRead: number;
12
+ readonly cacheWrite: number;
13
+ } | null;
14
+ /** "models.md" when the package cell parsed; else the ladder step that resolved it. */
15
+ readonly costSource: "models.md" | "models-page" | "detail" | "rsc";
5
16
  }
6
17
  export declare const MODEL_SNAPSHOT: readonly CatalogModel[];
@@ -1,74 +1,83 @@
1
1
  // src/catalog/snapshot.ts — GENERATED by scripts/refresh-snapshot.mjs. Do not edit.
2
2
  //
3
- // A copy of the Command Code model catalog (id, name, context length) bundled
4
- // in the package so the plugin can auto-register every model without network
5
- // access at runtime. Regenerate with `npm run refresh:snapshot`.
3
+ // A copy of the Command Code model catalog bundled in the package so the
4
+ // plugin can auto-register every model without network access at runtime.
5
+ // Since issue #130 the npm package models.md table is the sole membership
6
+ // authority: every models.md row ships here with its ship-bar fields
7
+ // (id, name, context length parsed from the coarse Context column, costs,
8
+ // efforts). Since issue #132 a blank models.md cell is resolved through
9
+ // the ordered enrichment ladders (context: RSC contextWindow → CLI
10
+ // contextWindow → carried-forward; cost: models page index → detail page
11
+ // → RSC rates — costs never carry forward), and each row carries its
12
+ // `contextSource` / `costSource` provenance. The listing API decides
13
+ // nothing and wins no field. Regenerate with `npm run refresh:snapshot`.
6
14
  export const MODEL_SNAPSHOT = [
7
- { id: "claude-sonnet-5", name: "Claude Sonnet 5", contextLength: 1000000 },
8
- { id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6", contextLength: 1000000 },
9
- { id: "claude-fable-5-1", name: "Claude Fable 5.1", contextLength: 1000000 },
10
- { id: "claude-fable-5", name: "Claude Fable 5", contextLength: 1000000 },
11
- { id: "claude-opus-5", name: "Claude Opus 5", contextLength: 1000000 },
12
- { id: "claude-opus-4-8", name: "Claude Opus 4.8", contextLength: 1000000 },
13
- { id: "claude-opus-4-7", name: "Claude Opus 4.7", contextLength: 1000000 },
14
- { id: "claude-haiku-4-5-20251001", name: "Claude Haiku 4.5", contextLength: 200000 },
15
- { id: "gpt-5.6-sol", name: "GPT-5.6 Sol", contextLength: 1050000 },
16
- { id: "gpt-5.6-terra", name: "GPT-5.6 Terra", contextLength: 1050000 },
17
- { id: "gpt-5.6-luna", name: "GPT-5.6 Luna", contextLength: 1050000 },
18
- { id: "gpt-5.5", name: "GPT-5.5", contextLength: 400000 },
19
- { id: "gpt-5.4", name: "GPT-5.4", contextLength: 400000 },
20
- { id: "gpt-5.3-codex", name: "GPT-5.3 Codex", contextLength: 400000 },
21
- { id: "gpt-5.4-mini", name: "GPT-5.4 Mini", contextLength: 400000 },
22
- { id: "deepseek/deepseek-v4-pro", name: "DeepSeek V4 Pro (latest)", contextLength: 1000000 },
23
- { id: "deepseek/deepseek-v4-flash", name: "DeepSeek V4 Flash (latest)", contextLength: 1000000 },
24
- { id: "deepseek/deepseek-v4-flash-vision-exp", name: "DeepSeek V4 Flash Vision (exp)", contextLength: 1000000 },
25
- { id: "deepseek/deepseek-v4-flash-fast", name: "DeepSeek V4 Flash Fast", contextLength: 1000000 },
26
- { id: "moonshotai/Kimi-K3", name: "Kimi K3", contextLength: 1000000 },
27
- { id: "moonshotai/Kimi-K2.7-Code", name: "Kimi K2.7 Code", contextLength: 256000 },
28
- { id: "moonshotai/Kimi-K2.7-Code-Highspeed", name: "Kimi K2.7 Code HighSpeed", contextLength: 262000 },
29
- { id: "moonshotai/Kimi-K2.6", name: "Kimi K2.6", contextLength: 256000 },
30
- { id: "moonshotai/Kimi-K2.5", name: "Kimi K2.5", contextLength: 256000 },
31
- { id: "z-ai/glm-5.3-flash", name: "GLM-5.3 Flash", contextLength: 1048576 },
32
- { id: "zai-org/GLM-5.3", name: "GLM-5.3", contextLength: 1000000 },
33
- { id: "zai-org/GLM-5.2", name: "GLM-5.2", contextLength: 1000000 },
34
- { id: "zai-org/GLM-5.2-Fast", name: "GLM-5.2 Fast", contextLength: 1000000 },
35
- { id: "zai-org/GLM-5.1", name: "GLM-5.1", contextLength: 200000 },
36
- { id: "zai-org/GLM-5", name: "GLM-5", contextLength: 200000 },
37
- { id: "MiniMaxAI/MiniMax-M3", name: "MiniMax M3", contextLength: 1000000 },
38
- { id: "MiniMaxAI/MiniMax-M2.7", name: "MiniMax M2.7", contextLength: 200000 },
39
- { id: "MiniMaxAI/MiniMax-M2.5", name: "MiniMax M2.5", contextLength: 200000 },
40
- { id: "xiaomi/mimo-v2.5-pro", name: "MiMo V2.5 Pro", contextLength: 1000000 },
41
- { id: "xiaomi/mimo-v2.5", name: "MiMo V2.5", contextLength: 1000000 },
42
- { id: "Qwen/Qwen3.8-Max-0902", name: "Qwen 3.8 Max 0902", contextLength: 1000000 },
43
- { id: "Qwen/Qwen3.8-Max", name: "Qwen 3.8 Max", contextLength: 1000000 },
44
- { id: "Qwen/Qwen3.8-27B", name: "Qwen 3.8 27B", contextLength: 262144 },
45
- { id: "Qwen/Qwen3.8-Flash", name: "Qwen 3.8 Flash", contextLength: 1000000 },
46
- { id: "Qwen/Qwen3.7-Max", name: "Qwen 3.7 Max", contextLength: 1000000 },
47
- { id: "Qwen/Qwen3.7-Plus", name: "Qwen 3.7 Plus", contextLength: 1000000 },
48
- { id: "Qwen/Qwen3.7-Flash", name: "Qwen 3.7 Flash", contextLength: 1000000 },
49
- { id: "Qwen/Qwen3.6-Max-Preview", name: "Qwen 3.6 Max Preview", contextLength: 200000 },
50
- { id: "Qwen/Qwen3.6-Plus", name: "Qwen 3.6 Plus", contextLength: 200000 },
51
- { id: "meituan/LongCat-2.0:free", name: "LongCat 2.0", contextLength: 1048576 },
52
- { id: "stepfun/Step-3.7-Flash", name: "Step 3.7 Flash", contextLength: 256000 },
53
- { id: "stepfun/Step-3.5-Flash", name: "Step 3.5 Flash", contextLength: 1000000 },
54
- { id: "tencent/hy3-paid", name: "Tencent Hy3", contextLength: 262144 },
55
- { id: "tencent/hy4-preview", name: "Tencent Hy4 Preview", contextLength: 1048576 },
56
- { id: "google/gemini-3.8-flash", name: "Gemini 3.8 Flash", contextLength: 1000000 },
57
- { id: "google/gemini-3.7-flash", name: "Gemini 3.7 Flash", contextLength: 1048576 },
58
- { id: "google/gemini-3.6-flash", name: "Gemini 3.6 Flash", contextLength: 1000000 },
59
- { id: "google/gemini-3.5-flash", name: "Gemini 3.5 Flash", contextLength: 1000000 },
60
- { id: "google/gemini-3.5-flash-lite", name: "Gemini 3.5 Flash Lite", contextLength: 1000000 },
61
- { id: "google/gemini-3.1-flash-lite", name: "Gemini 3.1 Flash Lite", contextLength: 1000000 },
62
- { id: "sakana/fugu-ultra", name: "Fugu Ultra", contextLength: 1000000 },
63
- { id: "nvidia/nemotron-3-ultra-550b-a55b", name: "Nemotron 3 Ultra", contextLength: 1000000 },
64
- { id: "thinkingmachines/inkling", name: "Inkling", contextLength: 256000 },
65
- { id: "thinkingmachines/inkling-small", name: "Inkling Small", contextLength: 1000000 },
66
- { id: "poolside/laguna-s-2.1-free", name: "Laguna S 2.1", contextLength: 256000 },
67
- { id: "meta/muse-spark-1.1", name: "Muse Spark 1.1", contextLength: 1048576 },
68
- { id: "meta/muse-spark-1.2", name: "Muse Spark 1.2", contextLength: 1048576 },
69
- { id: "meta/muse-spark-1.2-contributor", name: "Muse Spark 1.2 Contributor", contextLength: 1048576 },
70
- { id: "meta/muse-spark-1.3", name: "Muse Spark 1.3", contextLength: 1048576 },
71
- { id: "meta/muse-spark-1.3-contributor", name: "Muse Spark 1.3 Contributor", contextLength: 1048576 },
72
- { id: "xai/grok-4.5", name: "Grok 4.5", contextLength: 500000 },
73
- { id: "xai/grok-4.6", name: "Grok 4.6", contextLength: 500000 },
15
+ { id: "deepseek/deepseek-v4-pro", name: "DeepSeek V4 Pro (latest)", contextLength: 1000000, contextSource: "models.md", efforts: ["high", "max"], cost: { input: 0.66, output: 1.98, cacheRead: 0.022, cacheWrite: 0 }, costSource: "models.md" },
16
+ { id: "deepseek/deepseek-v4-flash", name: "DeepSeek V4 Flash (latest)", contextLength: 1000000, contextSource: "models.md", efforts: ["high", "max"], cost: { input: 0.22, output: 0.66, cacheRead: 0.007, cacheWrite: 0 }, costSource: "models.md" },
17
+ { id: "deepseek/deepseek-v4-flash-vision-exp", name: "DeepSeek V4 Flash Vision (exp)", contextLength: 1000000, contextSource: "models.md", efforts: ["high", "max"], cost: { input: 0.22, output: 0.66, cacheRead: 0.007, cacheWrite: 0 }, costSource: "models.md" },
18
+ { id: "deepseek/deepseek-v4-flash-fast", name: "DeepSeek V4 Flash Fast", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "high", "max"], cost: { input: 0.28, output: 0.56, cacheRead: 0.07, cacheWrite: 0 }, costSource: "models.md" },
19
+ { id: "moonshotai/Kimi-K3", name: "Kimi K3", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "high", "max"], cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 }, costSource: "models.md" },
20
+ { id: "moonshotai/Kimi-K2.7-Code", name: "Kimi K2.7 Code", contextLength: 256000, contextSource: "models.md", efforts: null, cost: { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 }, costSource: "models.md" },
21
+ { id: "moonshotai/Kimi-K2.7-Code-Highspeed", name: "Kimi K2.7 Code HighSpeed", contextLength: 262000, contextSource: "models.md", efforts: null, cost: { input: 1.9, output: 8, cacheRead: 0.38, cacheWrite: 0 }, costSource: "models.md" },
22
+ { id: "moonshotai/Kimi-K2.6", name: "Kimi K2.6", contextLength: 256000, contextSource: "models.md", efforts: null, cost: { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, costSource: "models.md" },
23
+ { id: "moonshotai/Kimi-K2.5", name: "Kimi K2.5", contextLength: 256000, contextSource: "models.md", efforts: null, cost: { input: 0.6, output: 3, cacheRead: 0.1, cacheWrite: 0 }, costSource: "models.md" },
24
+ { id: "z-ai/glm-5.3-flash", name: "GLM-5.3 Flash", contextLength: 1050000, contextSource: "models.md", efforts: ["low", "high", "max"], cost: { input: 0.15, output: 0.5, cacheRead: 0.03, cacheWrite: 0 }, costSource: "models.md" },
25
+ { id: "zai-org/GLM-5.3", name: "GLM-5.3", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "high", "max"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, costSource: "models.md" },
26
+ { id: "zai-org/GLM-5.2", name: "GLM-5.2", contextLength: 1000000, contextSource: "models.md", efforts: ["high", "max"], cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, costSource: "models.md" },
27
+ { id: "zai-org/GLM-5.2-Fast", name: "GLM-5.2 Fast", contextLength: 1000000, contextSource: "models.md", efforts: null, cost: { input: 3, output: 10.25, cacheRead: 0.5, cacheWrite: 0 }, costSource: "models.md" },
28
+ { id: "zai-org/GLM-5.1", name: "GLM-5.1", contextLength: 200000, contextSource: "rsc", efforts: null, cost: { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 }, costSource: "models.md" },
29
+ { id: "zai-org/GLM-5", name: "GLM-5", contextLength: 200000, contextSource: "models.md", efforts: null, cost: { input: 1, output: 3.2, cacheRead: 0.2, cacheWrite: 0 }, costSource: "models.md" },
30
+ { id: "MiniMaxAI/MiniMax-M3", name: "MiniMax M3", contextLength: 1000000, contextSource: "models.md", efforts: null, cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, costSource: "models.md" },
31
+ { id: "MiniMaxAI/MiniMax-M2.7", name: "MiniMax M2.7", contextLength: 200000, contextSource: "rsc", efforts: null, cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 }, costSource: "models.md" },
32
+ { id: "MiniMaxAI/MiniMax-M2.5", name: "MiniMax M2.5", contextLength: 200000, contextSource: "models.md", efforts: null, cost: { input: 0.3, output: 1.2, cacheRead: 0.03, cacheWrite: 0 }, costSource: "models.md" },
33
+ { id: "xiaomi/mimo-v2.5-pro", name: "MiMo V2.5 Pro", contextLength: 1000000, contextSource: "models.md", efforts: null, cost: { input: 0.435, output: 0.87, cacheRead: 0.0036, cacheWrite: 0 }, costSource: "models.md" },
34
+ { id: "xiaomi/mimo-v2.5", name: "MiMo V2.5", contextLength: 1000000, contextSource: "models.md", efforts: null, cost: { input: 0.14, output: 0.28, cacheRead: 0.0028, cacheWrite: 0 }, costSource: "models.md" },
35
+ { id: "Qwen/Qwen3.8-Max-0902", name: "Qwen 3.8 Max 0902", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "medium", "xhigh"], cost: { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 0 }, costSource: "models.md" },
36
+ { id: "Qwen/Qwen3.8-Max", name: "Qwen 3.8 Max", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "medium", "xhigh"], cost: { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 2.5 }, costSource: "models.md" },
37
+ { id: "Qwen/Qwen3.8-27B", name: "Qwen 3.8 27B", contextLength: 262000, contextSource: "models.md", efforts: ["low", "medium", "xhigh"], cost: { input: 0.4, output: 3, cacheRead: 0.04, cacheWrite: 0 }, costSource: "models.md" },
38
+ { id: "Qwen/Qwen3.8-Flash", name: "Qwen 3.8 Flash", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "medium", "xhigh"], cost: { input: 0.16, output: 0.47, cacheRead: 0.016, cacheWrite: 0 }, costSource: "models.md" },
39
+ { id: "Qwen/Qwen3.7-Max", name: "Qwen 3.7 Max", contextLength: 1000000, contextSource: "models.md", efforts: null, cost: { input: 2.5, output: 7.5, cacheRead: 0.5, cacheWrite: 3.13 }, costSource: "models.md" },
40
+ { id: "Qwen/Qwen3.7-Plus", name: "Qwen 3.7 Plus", contextLength: 1000000, contextSource: "models.md", efforts: null, cost: { input: 0.4, output: 1.6, cacheRead: 0.08, cacheWrite: 0.5 }, costSource: "models.md" },
41
+ { id: "Qwen/Qwen3.7-Flash", name: "Qwen 3.7 Flash", contextLength: 1000000, contextSource: "models.md", efforts: null, cost: { input: 0.03, output: 0.13, cacheRead: 0.006, cacheWrite: 0.038 }, costSource: "models.md" },
42
+ { id: "Qwen/Qwen3.6-Max-Preview", name: "Qwen 3.6 Max Preview", contextLength: 200000, contextSource: "rsc", efforts: null, cost: { input: 1.3, output: 7.8, cacheRead: 0.26, cacheWrite: 1.63 }, costSource: "models.md" },
43
+ { id: "Qwen/Qwen3.6-Plus", name: "Qwen 3.6 Plus", contextLength: 200000, contextSource: "rsc", efforts: null, cost: { input: 0.5, output: 3, cacheRead: 0.1, cacheWrite: 0 }, costSource: "models.md" },
44
+ { id: "meituan/LongCat-2.0:free", name: "LongCat 2.0", contextLength: 1050000, contextSource: "models.md", efforts: null, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, costSource: "models.md" },
45
+ { id: "stepfun/Step-3.7-Flash", name: "Step 3.7 Flash", contextLength: 256000, contextSource: "models.md", efforts: null, cost: { input: 0.2, output: 1.15, cacheRead: 0.04, cacheWrite: 0 }, costSource: "models.md" },
46
+ { id: "stepfun/Step-3.5-Flash", name: "Step 3.5 Flash", contextLength: 1000000, contextSource: "models.md", efforts: null, cost: { input: 0.1, output: 0.3, cacheRead: 0.02, cacheWrite: 0 }, costSource: "models.md" },
47
+ { id: "tencent/hy3-paid", name: "Tencent Hy3", contextLength: 262000, contextSource: "models.md", efforts: null, cost: { input: 0.14, output: 0.58, cacheRead: 0.035, cacheWrite: 0 }, costSource: "models.md" },
48
+ { id: "tencent/hy4-preview", name: "Tencent Hy4 Preview", contextLength: 1050000, contextSource: "models.md", efforts: ["low", "medium", "high"], cost: { input: 0.834, output: 2.501, cacheRead: 0.042, cacheWrite: 0 }, costSource: "models.md" },
49
+ { id: "nvidia/nemotron-3-ultra-550b-a55b", name: "Nemotron 3 Ultra", contextLength: 1000000, contextSource: "models.md", efforts: null, cost: { input: 0.6, output: 2.4, cacheRead: 0.12, cacheWrite: 0 }, costSource: "models.md" },
50
+ { id: "thinkingmachines/inkling", name: "Inkling", contextLength: 256000, contextSource: "models.md", efforts: null, cost: { input: 1, output: 4.05, cacheRead: 0.17, cacheWrite: 0 }, costSource: "models.md" },
51
+ { id: "thinkingmachines/inkling-small", name: "Inkling Small", contextLength: 1000000, contextSource: "models.md", efforts: null, cost: { input: 0.5, output: 1.2, cacheRead: 0.1, cacheWrite: 0 }, costSource: "models.md" },
52
+ { id: "poolside/laguna-s-2.1-free", name: "Laguna S 2.1", contextLength: 256000, contextSource: "models.md", efforts: null, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, costSource: "models.md" },
53
+ { id: "claude-sonnet-5", name: "Claude Sonnet 5", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh", "max"], cost: { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, costSource: "models.md" },
54
+ { id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh", "max"], cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, costSource: "models.md" },
55
+ { id: "claude-fable-5-1", name: "Claude Fable 5.1", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh", "max"], cost: { input: 10, output: 50, cacheRead: 0.25, cacheWrite: 12.5 }, costSource: "models.md" },
56
+ { id: "claude-fable-5", name: "Claude Fable 5", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh", "max"], cost: { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, costSource: "models.md" },
57
+ { id: "claude-opus-5", name: "Claude Opus 5", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh", "max"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, costSource: "models.md" },
58
+ { id: "claude-opus-4-8", name: "Claude Opus 4.8", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh", "max"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, costSource: "models.md" },
59
+ { id: "claude-opus-4-7", name: "Claude Opus 4.7", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh", "max"], cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, costSource: "models.md" },
60
+ { id: "claude-haiku-4-5-20251001", name: "Claude Haiku 4.5", contextLength: 200000, contextSource: "models.md", efforts: null, cost: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 }, costSource: "models.md" },
61
+ { id: "gpt-6-astra", name: "GPT-6 Astra", contextLength: 1050000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh", "max"], cost: { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, costSource: "models.md" },
62
+ { id: "gpt-5.6-sol", name: "GPT-5.6 Sol", contextLength: 1050000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh", "max"], cost: { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 6.25 }, costSource: "models.md" },
63
+ { id: "gpt-5.6-terra", name: "GPT-5.6 Terra", contextLength: 1050000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh", "max"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 }, costSource: "models.md" },
64
+ { id: "gpt-5.6-luna", name: "GPT-5.6 Luna", contextLength: 1050000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh", "max"], cost: { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, costSource: "models.md" },
65
+ { id: "gpt-5.5", name: "GPT-5.5", contextLength: 400000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh"], cost: { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, costSource: "models.md" },
66
+ { id: "gpt-5.4", name: "GPT-5.4", contextLength: 400000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh"], cost: { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, costSource: "models.md" },
67
+ { id: "gpt-5.3-codex", name: "GPT-5.3 Codex", contextLength: 400000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh"], cost: { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 }, costSource: "models.md" },
68
+ { id: "gpt-5.4-mini", name: "GPT-5.4 Mini", contextLength: 400000, contextSource: "models.md", efforts: ["low", "medium", "high"], cost: { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 }, costSource: "models.md" },
69
+ { id: "google/gemini-3.8-flash", name: "Gemini 3.8 Flash", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "medium", "high"], cost: { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 0 }, costSource: "models.md" },
70
+ { id: "google/gemini-3.7-flash", name: "Gemini 3.7 Flash", contextLength: 1050000, contextSource: "models.md", efforts: ["low", "medium", "high"], cost: { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 0.08334 }, costSource: "models.md" },
71
+ { id: "google/gemini-3.6-flash", name: "Gemini 3.6 Flash", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "medium", "high"], cost: { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 0 }, costSource: "models.md" },
72
+ { id: "google/gemini-3.5-flash", name: "Gemini 3.5 Flash", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "medium", "high"], cost: { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0 }, costSource: "models.md" },
73
+ { id: "google/gemini-3.5-flash-lite", name: "Gemini 3.5 Flash Lite", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "medium", "high"], cost: { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0 }, costSource: "models.md" },
74
+ { id: "google/gemini-3.1-flash-lite", name: "Gemini 3.1 Flash Lite", contextLength: 1000000, contextSource: "models.md", efforts: ["low", "medium", "high"], cost: { input: 0.25, output: 1.5, cacheRead: 0.03, cacheWrite: 0 }, costSource: "models.md" },
75
+ { id: "sakana/fugu-ultra", name: "Fugu Ultra", contextLength: 1000000, contextSource: "models.md", efforts: ["high", "xhigh"], cost: { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 }, costSource: "models.md" },
76
+ { id: "meta/muse-spark-1.1", name: "Muse Spark 1.1", contextLength: 1050000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh"], cost: { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, costSource: "models.md" },
77
+ { id: "meta/muse-spark-1.2", name: "Muse Spark 1.2", contextLength: 1050000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh"], cost: { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, costSource: "models.md" },
78
+ { id: "meta/muse-spark-1.2-contributor", name: "Muse Spark 1.2 Contributor", contextLength: 1050000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh"], cost: { input: 0.1, output: 0.2, cacheRead: 0.002, cacheWrite: 0 }, costSource: "models.md" },
79
+ { id: "meta/muse-spark-1.3", name: "Muse Spark 1.3", contextLength: 1050000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh", "max"], cost: { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 }, costSource: "models.md" },
80
+ { id: "meta/muse-spark-1.3-contributor", name: "Muse Spark 1.3 Contributor", contextLength: 1050000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh"], cost: { input: 0.1, output: 0.2, cacheRead: 0.002, cacheWrite: 0 }, costSource: "models.md" },
81
+ { id: "xai/grok-4.5", name: "Grok 4.5", contextLength: 500000, contextSource: "models.md", efforts: ["low", "medium", "high"], cost: { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, costSource: "models.md" },
82
+ { id: "xai/grok-4.6", name: "Grok 4.6", contextLength: 500000, contextSource: "models.md", efforts: ["low", "medium", "high", "xhigh"], cost: { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 }, costSource: "models.md" },
74
83
  ];
@@ -51,5 +51,5 @@ export interface ModelDeals {
51
51
  export declare const MODEL_DEALS: Readonly<Record<string, ModelDeals>>;
52
52
  export declare const PLAN_CATALOG: Readonly<Record<PlanId, PlanInfo>>;
53
53
  export declare const DEAL_SOURCE_URL = "https://commandcode.ai/docs/resources/pricing-limits";
54
- export declare const DEAL_LAST_REFRESHED = "2026-09-03";
54
+ export declare const DEAL_LAST_REFRESHED = "2026-09-06";
55
55
  export declare const DEAL_PACKAGE_VERSION = "docs";
@@ -30,6 +30,7 @@ export const MODEL_DEALS = {
30
30
  "gpt-5.6-luna": { tier: "opensource", benchmark: { "intelligence": 52.3, "tokPerSec": 124.1 }, overContext: { "input": 0.4, "output": 1.8, "cacheRead": 0.04, "cacheWrite": 0.5 }, free: false, allowance: { "goat": 20, "pro": 30 } },
31
31
  "gpt-5.6-sol": { tier: "opensource", benchmark: { "intelligence": 60.9, "tokPerSec": 69.6 }, overContext: { "input": 10, "output": 45, "cacheRead": 1, "cacheWrite": 12.5 }, free: false, allowance: { "goat": 70, "pro": 80 } },
32
32
  "gpt-5.6-terra": { tier: "premium", benchmark: { "intelligence": 56.6, "tokPerSec": 112.8 }, overContext: { "input": 4, "output": 18, "cacheRead": 0.4, "cacheWrite": 5 }, free: false, allowance: { "goat": 20, "pro": 20 } },
33
+ "gpt-6-astra": { tier: "premium", overContext: { "input": 20, "output": 75, "cacheRead": 2, "cacheWrite": 25 }, free: false, allowance: { "goat": 20, "pro": 20 } },
33
34
  "meituan/LongCat-2.0:free": { tier: "opensource", free: true },
34
35
  "meta/muse-spark-1.1": { tier: "premium", benchmark: { "intelligence": 53.2 }, free: false, allowance: { "goat": 20, "pro": 20 } },
35
36
  "meta/muse-spark-1.2": { tier: "opensource", benchmark: { "intelligence": 56.8 }, free: false, allowance: { "goat": 20, "pro": 30 } },
@@ -83,5 +84,5 @@ export const PLAN_CATALOG = {
83
84
  provider: { price: 15, credits: 0, window5h: 0, windowWeek: 0, display: "Provider" },
84
85
  };
85
86
  export const DEAL_SOURCE_URL = "https://commandcode.ai/docs/resources/pricing-limits";
86
- export const DEAL_LAST_REFRESHED = "2026-09-03";
87
+ export const DEAL_LAST_REFRESHED = "2026-09-06";
87
88
  export const DEAL_PACKAGE_VERSION = "docs";
@@ -1,8 +1,16 @@
1
- import { MODEL_COSTS, ZERO_MODEL_COST, isFreeModelCost, } from "../provider/pricing.js";
1
+ import { isFreeModelCost } from "../provider/pricing.js";
2
2
  import { reasoningVariantsForModel, isReasoningModel } from "../provider/reasoning.js";
3
3
  import { inputModalitiesForModel } from "../provider/modalities.js";
4
4
  const DEFAULT_MAX_OUTPUT_TOKENS = 65_536;
5
5
  export const DEFAULT_DISPLAY_PREFIX = "[CMD] ";
6
+ // Context advertised for a snapshot row whose models.md Context cell is
7
+ // missing ("—"): the row ships as pending-context (issue #130) and the
8
+ // fallback ladder lands in #132. OpenCode requires a numeric limit, so a
9
+ // conservative placeholder keeps the model usable — it is deliberately
10
+ // NOT the listing API's value (the API wins no ship-bar field) and NOT
11
+ // any carried-forward number: a reviewer sees the real gap in the
12
+ // refresh log's "context pending" note and the #132 ladder resolves it.
13
+ const PENDING_CONTEXT_LENGTH = 128_000;
6
14
  /**
7
15
  * Resolves the auto-registration display-name prefix from the user-declared
8
16
  * `provider.commandcode.options.display_prefix` key. A string value is used
@@ -91,21 +99,34 @@ export function augmentConfigCommandCodeModels(config) {
91
99
  * prefixed display name, context/output limits with output capped at
92
100
  * 65_536, and metadata enriched from the reasoning, modality, and pricing
93
101
  * tables.
102
+ *
103
+ * Ship-bar fields come from the snapshot row itself (issue #130: the
104
+ * models.md row is the authority; the listing API wins no field):
105
+ * - contextLength null (the models.md Context cell was "—") falls back to
106
+ * the OpenCode default context — never 0, never a fabricated API value;
107
+ * - cost null (the price cell was "—") advertises NO cost entry — missing
108
+ * never zero-fills (only an explicit all-zero cell means free).
94
109
  */
95
110
  function configModelFor(model, prefix = DEFAULT_DISPLAY_PREFIX) {
96
111
  const variants = reasoningVariantsForModel(model.id);
97
- const costs = MODEL_COSTS[model.id] ?? ZERO_MODEL_COST;
98
- // Upstream names the paid and free MiniMax variants identically
99
- // (`MiniMax M3` / `MiniMax M2.7`); append `(free)` to the picker entry so
100
- // users can tell them apart. Data-driven from the zero cost table a model
101
- // is only "free" when the catalog has an actual zero-cost entry (an absent
102
- // entry falls back to ZERO_MODEL_COST and is NOT free).
103
- const freeSuffix = MODEL_COSTS[model.id] !== undefined && isFreeModelCost(costs) ? " (free)" : "";
112
+ // The row's own parsed price is the ship-bar authority. A null cost
113
+ // (missing models.md price cell) advertises no cost entry — the
114
+ // zero-cost defensive fallback (ZERO_MODEL_COST) is deliberately not
115
+ // used here: a missing price must never read as a $0 model (the parent
116
+ // spec's "missing never zero-fills").
117
+ const rowCost = model.cost;
118
+ const freeSuffix = rowCost !== null && isFreeModelCost(rowCost) ? " (free)" : "";
119
+ // OpenCode requires a numeric context limit. A package row whose Context
120
+ // cell is missing ships as pending-context (issue #130) and must not read
121
+ // as 0 — that would advertise a broken model. PENDING_CONTEXT_LENGTH is
122
+ // a conservative placeholder for such a row until the ladder (issue
123
+ // #132) resolves it.
124
+ const contextLength = model.contextLength ?? PENDING_CONTEXT_LENGTH;
104
125
  return {
105
126
  name: `${prefix}${model.name}${freeSuffix}`,
106
127
  limit: {
107
- context: model.contextLength,
108
- output: Math.min(model.contextLength, DEFAULT_MAX_OUTPUT_TOKENS),
128
+ context: contextLength,
129
+ output: Math.min(contextLength, DEFAULT_MAX_OUTPUT_TOKENS),
109
130
  },
110
131
  reasoning: isReasoningModel(model.id) ? true : undefined,
111
132
  variants: variants,
@@ -118,12 +139,16 @@ function configModelFor(model, prefix = DEFAULT_DISPLAY_PREFIX) {
118
139
  modalities: {
119
140
  input: [...inputModalitiesForModel(model.id)],
120
141
  },
121
- cost: {
122
- input: costs.input,
123
- output: costs.output,
124
- cache_read: costs.cacheRead,
125
- cache_write: costs.cacheWrite,
126
- },
142
+ ...(rowCost !== null
143
+ ? {
144
+ cost: {
145
+ input: rowCost.input,
146
+ output: rowCost.output,
147
+ cache_read: rowCost.cacheRead,
148
+ cache_write: rowCost.cacheWrite,
149
+ },
150
+ }
151
+ : {}),
127
152
  status: "active",
128
153
  };
129
154
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-cmd-provider",
3
- "version": "1.6.4",
3
+ "version": "1.7.0",
4
4
  "description": "Command Code provider + plugin for opencode",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -23,7 +23,7 @@
23
23
  "refresh:classification": "node scripts/refresh-classification.mjs",
24
24
  "refresh": "npm run refresh:snapshot && npm run refresh:fixtures && npm run refresh:classification -- --fixtures && npm run refresh:deals -- --fixtures",
25
25
  "test": "npm run typecheck && npm run test:unit && npm run test:integration && npm run test:contract && npm run format:check",
26
- "test:unit": "tsx tests/env.test.ts && tsx tests/auth-key.test.ts && tsx tests/converters.test.ts && tsx tests/stream.test.ts && tsx tests/provider-codecs.test.ts && tsx tests/provider-transport.test.ts && tsx tests/provider-parity.test.ts && tsx tests/provider-upgrade-fallback.test.ts && tsx tests/provider-zdr.test.ts && tsx tests/redact.test.ts && tsx tests/cost.test.ts && tsx tests/retry.test.ts && tsx tests/reasoning.test.ts && tsx tests/modalities.test.ts && tsx tests/snapshot.test.ts && tsx tests/refresh-snapshot.test.ts && tsx tests/oauth.test.ts && tsx tests/auth-mirror.test.ts && tsx tests/parse-facts.test.ts && tsx tests/parse-modalities.test.ts && tsx tests/catalog-metadata.test.ts && tsx tests/plugin-models.test.ts && tsx tests/vendor.test.ts && tsx tests/deals-enrichment.test.ts && tsx tests/deals-coverage.test.ts && tsx tests/plan-summary.test.ts && tsx tests/html-tables.test.ts && tsx tests/parse-docs.test.ts && tsx tests/parse-rsc.test.ts && tsx tests/rsc-source.test.ts && tsx tests/classification-overrides.test.ts && tsx tests/refresh-classification.test.ts && tsx tests/classification.test.ts && tsx tests/no-upstream-value-pins.test.ts && tsx tests/mock-cc-rsc.test.ts && tsx tests/capture-rsc-fixtures.test.ts && tsx tests/refresh-deals.test.ts && tsx tests/refresh-deals-rsc.test.ts && tsx tests/tier-overrides.test.ts && tsx tests/tui-deals-panel.test.ts && tsx tests/diff-catalog.test.ts && tsx tests/catalog-refresh-extract.test.ts && tsx tests/catalog-refresh-drift.test.ts && tsx tests/catalog-refresh-push.test.ts && tsx tests/auto-release.test.ts && tsx tests/replay-verification.test.ts && tsx tests/plugin-install.test.ts",
26
+ "test:unit": "tsx tests/env.test.ts && tsx tests/auth-key.test.ts && tsx tests/converters.test.ts && tsx tests/stream.test.ts && tsx tests/provider-codecs.test.ts && tsx tests/provider-transport.test.ts && tsx tests/provider-parity.test.ts && tsx tests/provider-upgrade-fallback.test.ts && tsx tests/provider-zdr.test.ts && tsx tests/redact.test.ts && tsx tests/cost.test.ts && tsx tests/retry.test.ts && tsx tests/reasoning.test.ts && tsx tests/modalities.test.ts && tsx tests/snapshot.test.ts && tsx tests/refresh-snapshot.test.ts && tsx tests/api-demotion.test.ts && tsx tests/ladders.test.ts && tsx tests/retire-prune.test.ts && tsx tests/enrichment-sections.test.ts && tsx tests/oauth.test.ts && tsx tests/auth-mirror.test.ts && tsx tests/parse-facts.test.ts && tsx tests/parse-modalities.test.ts && tsx tests/catalog-metadata.test.ts && tsx tests/plugin-models.test.ts && tsx tests/vendor.test.ts && tsx tests/deals-enrichment.test.ts && tsx tests/deals-coverage.test.ts && tsx tests/plan-summary.test.ts && tsx tests/html-tables.test.ts && tsx tests/parse-docs.test.ts && tsx tests/parse-rsc.test.ts && tsx tests/parse-models-page.test.ts && tsx tests/rsc-source.test.ts && tsx tests/classification-overrides.test.ts && tsx tests/refresh-classification.test.ts && tsx tests/classification.test.ts && tsx tests/no-upstream-value-pins.test.ts && tsx tests/mock-cc-rsc.test.ts && tsx tests/capture-rsc-fixtures.test.ts && tsx tests/refresh-deals.test.ts && tsx tests/refresh-deals-rsc.test.ts && tsx tests/tier-overrides.test.ts && tsx tests/tui-deals-panel.test.ts && tsx tests/diff-catalog.test.ts && tsx tests/catalog-refresh-extract.test.ts && tsx tests/catalog-refresh-drift.test.ts && tsx tests/catalog-refresh-push.test.ts && tsx tests/auto-release.test.ts && tsx tests/replay-verification.test.ts && tsx tests/plugin-install.test.ts",
27
27
  "test:integration": "tsx tests/integration-do-stream.test.ts && tsx tests/integration-do-generate.test.ts",
28
28
  "test:contract": "tsx tests/contract.test.ts",
29
29
  "test:e2e": "node tests/e2e-opencode.mjs",