Files
DeepSeek-Reasonix/docs/MODEL_IDENTITY.md
T
SivanCola c1cec65e69 feat(provider,config,billing): adapt official DeepSeek to the V4.1 Flash launch
Problem
-------
The official DeepSeek provider still modelled the pre-V4.1 world. DeepSeek
shipped V4.1 Flash as `deepseek-flash` with native image input, retired
`deepseek-v4-flash-vision-exp`, cut the Flash price from 2026-09-10 12:00
Beijing, and left `deepseek-v4-flash` / `deepseek-v4-pro` as transition
aliases. The desktop model list therefore showed `deepseek-flash` as "image
capability unknown", `deepseek-v4-flash` was hard-blocked from images even
though it now serves a multimodal model, and every cost quote was priced on
the superseded August table.

Root cause
----------
Image capability had no single owner: the settings resolver read
`BuiltinModelInfo` and the curated preset, the runtime gate read the
pinned-SKU check inside `officialDeepSeekEffectiveVision`, and a separate
hard text-only block keyed on an exact two-model list. Adding a SKU meant
editing several lists that could silently disagree. Pricing had the same
shape: `ResolveScheduledRate` hardcoded one schedule id, and `LookupCatalog`
returned the first peak row, so a second dated schedule could not be
expressed.

Fix
---
- `internal/provider/deepseek_models.go` owns the official DeepSeek model
  lists. `IsOfficialDeepSeekImageModel` covers V4.1 Flash and the ids the
  vendor still routes to it; `IsOfficialDeepSeekTextModel` is now V4 Pro
  only. The capability resolver, the runtime vision gate and the local model
  catalog all consult it, so a new SKU is added in one place.
- An explicitly emptied `VisionModels` list still disables image input for a
  provider; only a stale non-empty list is allowed to omit a model the
  vendor reports as capable.
- `internal/billing/catalog.go` gains `ScheduleDeepSeekV4September2026`
  (2026-09-10 04:00 UTC). The August rows close at the cutover so the
  superseded prices stay queryable, and the retired ids are billed at the
  Flash price. `LookupCatalog` selects the newest peak anchor, and the new
  `MatchesOfficialPeakAnchor` accepts an anchor from any generation, so a
  config saved before the price cut is still quoted at the live rate.
- `internal/config/pricing.go` carries the new Flash table and recognises
  the August generation as an official default instead of a custom rate.

The config version is deliberately unchanged:
`ApplyUserConfigUpgradesOnStartup` stamps
`deepSeekOfficialChatUpgradeConfigVersion` (9) for any config below the
current version, which would downgrade a v10 config while also skipping the
OpenCode Go upgrade that follows it. The refresh is done at quote time
instead, so no user config is rewritten on startup.

Verification
------------
- `go test ./...` (root): 131 packages ok. The 3 remaining failures reproduce
  on a pristine `origin/main-v2` checkout: untracked `wt*/` worktrees inside
  the repo are scanned by the sub-agent boundary test, and
  `cmd/reasonix-legacy-migrator` reads a real installation on this machine.
- `cd desktop && go test ./...`: ok.
- `golangci-lint` 2.12.2: 0 issues. `repolint`: clean, baseline unchanged.
- New coverage: `TestOfficialDeepSeekMultimodalSKUsEmbedUserImages` (image
  parts reach the wire), `TestDeepSeekSeptemberScheduleResolvesFlashPriceCut`
  (peak/off-peak, both currencies, legacy ids, V4 Pro unchanged, August
  schedule closed), and `TestStaleDeepSeekAnchorQuotesAtTheLiveRate`
  (end-to-end quote from a config still holding the August anchor).
2026-09-10 18:48:49 +08:00

1.8 KiB

Model IDs and capability overrides

Model IDs are case-sensitive identifiers. Reasonix preserves their spelling when saving configuration and sending requests. Model-A and model-a may coexist, but their image capability, context window, output limit, and reasoning overrides are independent. Model search may ignore case without changing the selected ID.

Use the exact ID accepted by the configured API endpoint. Display names and aliases are not implicit alternate spellings: if a service exposes an alias, configure that exact API identifier. Reasonix does not infer aliases by folding case. Adding a model validates its ID and numeric settings locally; a connection test determines whether the endpoint accepts it. An unlisted model can still be callable.

Unknown DeepSeek models allow manual image capability declarations. This does not prove that the endpoint supports images. The official DeepSeek models with native image input are deepseek-flash, deepseek-v4-flash, deepseek-v4.1-flash-expires-on-0910, and deepseek-v4-flash-vision-exp; V4 Pro remains text-only and blocked. A non-empty vision list curated before those models existed does not veto them, but an explicitly emptied list still disables image input for the provider. Video and PDF transport are not enabled by this setting.

Existing configuration

The configuration format is unchanged. Existing exact-ID settings continue to work. Overrides or legacy vision-list entries whose capitalization differs from the configured model ID are retained but no longer applied to that model. Correct the keys to match the actual ID; do not automatically lowercase them. An older Reasonix version may still apply its previous case-insensitive fallback when reading the same file, so it does not provide the new isolation guarantee.