Models
The desktop app's two model sources - your hosted models and the user's own coding CLIs - what the Models screen controls, and who pays for a run.
One rule decides everything here: a model appears in a picker only where that surface can actually reach it. The app reaches two runtimes, so most surfaces offer both and the ones the on-device runtime fires offer only its own.
| Source | Group in the picker | Runs on | Who pays |
|---|---|---|---|
Built-in models - config.ai.builtin | Built-in (Uses credits) | your server, via /ai/chat | your credit balance |
The user's own API keys - config.ai.byok | API providers (Your API key) | your server, via /ai/chat | the user's own provider key |
| Connected coding CLIs - Claude Code, Codex, Grok, OpenCode | Coding CLIs (Your subscription) | the user's machine | the user's own CLI login |
The hosted panes come from GET /ai/models, already scoped to the signed-in user, so nothing on the desktop decides entitlement. A CLI pane appears when the on-device runtime reports that CLI connected, and a failed read counts as not connected.
A user who installs nothing still has a model. With config.ai.builtin on, the built-in provider is ready the moment they sign in - no CLI, no key, no setup. That is the lane a new install lands on.
Which lane a turn runs on
The selection key names its own lane, and nothing else decides it - so a model chosen on an older build still reaches the runtime that can run it.
| Key shape | Lane | Metering |
|---|---|---|
<cli>@local[@<model>] | the on-device runtime drives that CLI | none - the user's own subscription |
platform::<id> or <provider>::<id> | your backend's /ai/chat route | server-side, by construction |
Metering cannot be skipped from here. The chat route builds the model already wrapped in its credits middleware, so a desktop turn is billed exactly as the identical browser turn is.
The Models screen
Settings > Models holds one Providers section, the model rows, and the on-device runtime's own controls.
- Providers: the hosted panes first, then the coding CLIs on this machine with their real state - connected, one-click connectable, needs sign-in, or not installed. Install fetches a missing CLI into the app's own folder; Update all refreshes every CLI the app installed. A CLI the user installed themselves is reported as theirs and never touched, and sign-in always runs under their own account.
- Default model: the model new chats open with, stored on this device. Picking a model in the chat composer sets it too - there is one model choice, not a separate per-chat one. An open chat that has not been re-pointed follows a change to it.
- Fallback model: the CLI a run retries under when the primary fails to START, never once it has produced output. On-device lane only.
- Models per CLI: each CLI offers the models its own provider serves, resolved from the public models.dev catalog (cached for an hour, no account data sent). A small built-in catalog seeds the picker instantly and covers offline.
Provider keys are managed on the web app. The desktop Providers section shows which vendors the account has keyed and links out to add, rotate or remove one - it never stores a key itself. The built-in card has no menu at all: your own key backs it, so there is nothing for the user to manage or break.
Where each source is offered
| Surface | Hosted models | Coding CLIs |
|---|---|---|
| Chat, and the side-panel Chat tab | yes | yes |
| Default and Fallback model rows | yes | yes |
| Automations | no | yes |
| Tasks | no | yes |
Automations and per-task overrides are fired by the on-device runtime against a coding CLI, so hosted models are not offered there - and a device default set to a hosted model reads as no default on those two surfaces, leaving them on the runtime's own staged default.
Subscription mode
A coding CLI runs under the user's own subscription - their existing claude / codex login, exactly as in a plain terminal. The app drives whichever auth mode the CLI reports and never reads or replays another app's credentials.
Subscription mode for some tools (Claude Code, for example) is not permitted for distributed third-party products without the tool vendor's prior approval, and may put the end user's account at risk. You and your end users remain solely responsible for complying with each tool vendor's terms of service.
The set of drivable CLIs is maintained in the agent runtime, not the desktop UI, and the runtime ships inside the app - so a newly drivable CLI arrives with an app update, with nothing else to install.