| 1 | # Model capability metadata |
| 2 | |
| 3 | Reasonix resolves input capabilities per model through the provider adapter. |
| 4 | Adapters return `inputModalities` for the exact model, following the |
| 5 | `deepseek-harness` model contract: |
| 6 | |
| 7 | - `text` means text input is accepted. |
| 8 | - `image` means native image input is accepted. |
| 9 | - `text + image` enables native multimodal requests without a `VisionModels` |
| 10 | setting. |
| 11 | |
| 12 | OpenAI-compatible `/models` responses may use the canonical |
| 13 | `input_modalities` field. Reasonix also accepts `modalities.input`, |
| 14 | `capabilities.input_modalities`, `capabilities.vision`, `supports_vision`, and |
| 15 | `vision` as compatibility aliases. Missing, malformed or conflicting declarations |
| 16 | remain **unknown** (`nil` internally; `[]` in the Desktop view). A valid text-only |
| 17 | declaration is **unsupported**; an image declaration is **supported**. Standard |
| 18 | fields take priority over aliases, including when the standard value is invalid. |
| 19 | Duplicate IDs merge independently of response order: unknown observations do not |
| 20 | erase valid facts, and contradictory facts remain unknown. Model names are never |
| 21 | used to guess image support. |
| 22 | |
| 23 | Dynamic metadata is stored in the disposable |
| 24 | `model-capabilities-v2.json` cache under the Reasonix cache directory. It is |
| 25 | not written to `config.toml`. Existing `vision` and `vision_models` entries |
| 26 | remain readable for backwards compatibility and take precedence over dynamic |
| 27 | metadata. V2 neither reads nor changes V1: the old cache cannot distinguish |
| 28 | missing metadata from a negative declaration. Custom models relying only on V1 |
| 29 | positive metadata need one model-list refresh or a manual override. Cache entries |
| 30 | expire after 24 hours; failed requests do not replace successful entries, while a |
| 31 | successful ID-only response records unknown. Route and credential changes isolate |
| 32 | the cache; late requests cannot replace newer successful discoveries. |
| 33 | |
| 34 | Built-in adapters also ship verified local catalogs for all untouched curated |
| 35 | provider presets. The catalogs cover the official OpenCode Go routes, the |
| 36 | DeepSeek vision SKU, ModelScope Qwen3.5 SKUs, and the remaining preset model |
| 37 | lists. They work without a model-list request; a custom endpoint, edited preset, |
| 38 | or model not in a local catalog stays unknown unless another valid source applies. |
| 39 | |
| 40 | ## Set image input for a relay model |
| 41 | |
| 42 | 1. In Settings → Models, add or edit the provider and fetch its model list. |
| 43 | 2. Select the model. If it shows “Image capability unknown”, confirm support with |
| 44 | the service provider and choose **Image input → On**. |
| 45 | 3. Save, then send an image after the runtime rebuild succeeds. Refreshing the |
| 46 | list and restarting the app preserve the choice. |
| 47 | |
| 48 | Both the provider editor and refreshed model picker offer **Auto / On / Off**. |
| 49 | On is your declaration of support, not a paid client probe. Off prevents native |
| 50 | image input even for catalogued visual models. Auto removes only the model's |
| 51 | `vision` override; context/output/reasoning settings remain intact. Auto can say |
| 52 | “Using legacy configuration” when an older `vision`/`vision_models` value applies. |
| 53 | |
| 54 | ```toml |
| 55 | [providers.model_overrides.example-model] |
| 56 | vision = true # false disables; remove this field for Auto |
| 57 | ``` |
| 58 | |
| 59 | Final priority is official protocol restriction → per-model override → existing |
| 60 | automatic chain (curated preset, legacy config, exact local catalog, valid online |
| 61 | cache) → unknown. Official DeepSeek text models remain blocked; its visual model |
| 62 | can be explicitly disabled. Capability changes preserve catalog context, output, |
| 63 | API and reasoning metadata. Discovery never saves UI-provided capabilities as facts. |
| 64 | |
| 65 | Idle active sessions rebuild after saving. Other open sessions check before the |
| 66 | next turn; an in-flight request retains its frozen capability and payload. Failed |
| 67 | or deferred rebuilds must finish before the setting is effective. The composer |
| 68 | reads the running Controller snapshot. No failed request or historical image is |
| 69 | automatically resent, and sending a message never fetches `/models`. |
| 70 | |
| 71 | System prompts, tool schemas and text-only serialization stay unchanged. Changing |
| 72 | image capability can change the projection of image-bearing history, so cache hits |
| 73 | for such conversations are not guaranteed across a rebuild. |
| 74 | |
| 75 | The broader provider/model catalog is sourced from the MIT-licensed |
| 76 | `github.com/sky-valley/pi/ai` Go port of Pi. Reasonix uses its embedded model |
| 77 | data only (`GetModels`/`Model.Input` and related facts), not its Agent or |
| 78 | Provider runtime. The dependency is pinned in `go.mod`; catalog updates must |
| 79 | be reviewed as data and license changes. |
| 80 | |
| 81 | Dependabot opens a dedicated weekly `sky-valley/pi` update PR instead of |
| 82 | bundling it with unrelated Go upgrades. The catalog contract tests in |
| 83 | `internal/provider/opencode_go_test.go` fail when important model capabilities |
| 84 | drift, so an update is merged only after its provider/API/endpoint diff is |
| 85 | reviewed. |
| 86 | |
| 87 | Text-only and unknown models use the existing `Agent.VisionModel`, OCR, and MCP |
| 88 | vision fallback paths. Raw image payloads are never sent to those models. |
| 89 |