Model catalog¶
For the administrator workflow, see Manage models. This page describes the version-1 JSON document and its runtime behavior.
Document format¶
A minimal catalog for an existing local model server:
{
"version": 1,
"default_model": "local-assistant",
"models": [
{
"id": "local-assistant",
"label": "Local assistant",
"provider": "local",
"wire_api": "openai_chat",
"api_model": "your-server-model-id"
}
]
}
Replace api_model with the ID served by your endpoint. This example declares
a text-only model without reasoning. Set capabilities to match your model
before using reasoning or multimodal inputs.
| Top-level field | Required value |
|---|---|
version |
Integer 1 |
default_model |
ID of an enabled entry in models |
models |
Between 1 and 1,000 model entries |
Unknown fields are rejected at both document and model level.
Model fields¶
| Field | Default | Meaning |
|---|---|---|
id |
Required | Stable Numi identifier stored by chats; 1–256 characters, no whitespace or control characters |
label |
Required | Display name; 1–160 characters |
provider |
Required | Provider settings to use; see Providers |
wire_api |
openai_chat |
openai_chat, openai_responses, or anthropic_messages |
api_model |
null |
Upstream ID; falls back to id |
hint |
Empty string | Short description, up to 1,000 characters |
enabled |
true |
Whether users can select the entry when its provider is configured |
input_modalities |
[] |
Unique non-text inputs from image, video, audio; text is implicit |
context_window |
null |
Token window, at least 1,024; overrides the provider fallback for request budgeting and compaction |
supports_prompt_cache |
false |
Whether Numi should apply supported prompt-cache handling |
supports_reasoning |
false |
Enables reasoning capabilities |
reasoning_mode |
none |
Request control: native, effort, enabled, or none |
preserve_reasoning |
false |
Requests replay of returned reasoning where the wire protocol supports it |
reasoning_mandatory |
false |
Prevents disabling reasoning |
reasoning_efforts |
[] |
Unique effort names supported by the route |
reasoning_default_effort |
null |
Default effort; must belong to the list when a list is given |
reasoning_default_enabled |
null |
Provider's default reasoning state |
IDs must be unique. Routes must also be unique by
(provider, wire_api, api_model or id). Keep IDs stable once chats reference
them; disable a referenced model instead of deleting it.
context_window is supported in catalog JSON, model creation, and imports. The
current Models form and per-model update schema do not expose it; use an import
or edit the complete private JSON document to change it.
Schema validation does not check endpoint health or every provider/protocol
pairing. anthropic_messages uses the anthropic or anthropic_compat settings;
select the matching provider for that wire API.
Non-reasoning entries use reasoning_mode: "none" and cannot declare
preservation, mandatory reasoning, or effort metadata. Reasoning entries
must choose a different mode. Mandatory reasoning cannot be disabled by
default.
For OpenRouter, use discovery or Refresh provider metadata in the Models
page to populate supported levels. Numi's chat setting uses off to disable
optional reasoning; it is not an effort to advertise for a mandatory model.
See Reasoning effort and
Preserved reasoning for request,
storage, and replay behavior.
Packaged models overview¶
The current packaged entries live in
src/numi_chat/llm/models.default.json. Inspect that file or the Models page
for model IDs and capabilities. Provider discovery can refresh advertised
metadata; a model description is not a remote availability check.
| State | Meaning |
|---|---|
| Configured | An entry exists in the active catalog |
| Enabled | The operator has enabled the entry |
| Available | Its provider settings exist |
| Selectable | It is enabled and its provider is available |
Disabled entries remain resolvable for history. Provider availability does not prove endpoint health or change the configured default.
Catalog precedence and persistence¶
The packaged file is application data. If NUMI_CHAT_MODEL_CONFIG_PATH
exists, that private file is the complete catalog; it is not merged with
packaged defaults. The path defaults to state/models.json, or
/app/state/models.json in Docker.
Admin writes validate the document and atomically replace the private file before activating a new snapshot. Invalid private JSON prevents startup; an invalid runtime reload leaves the last known-good snapshot active. Credentials and base URLs remain in environment settings, not catalog exports.
Each process checks the private file revision while reading the catalog. Writers are serialized only within one process; separate containers need a shared state directory to observe the same file. Mount the complete state directory so atomic replacement works.