AI agents
The desktop app's AI surface - Chat, Automations, and the AI settings screens - running on your hosted models or on the user's own coding CLIs.
The desktop app chats on your models out of the box, and gains a second runtime when the user brings their own: their installed coding CLIs (Claude Code, Codex, Grok, OpenCode) do the work on their machine, under their own logins, driven by the agent runtime the app forks. config.desktop.agents in packages/config/src/desktop.mjs gates the whole surface, which every desktop project ships in source - so turning it on is a config change, not a re-scaffold.
| Field | Default | Description |
|---|---|---|
enabled | true when scaffolded with AI, else false | Whether the AI surface renders and the app forks the runtime. Off, the app is a plain client shell: no AI pages, no side panel, no provider ever contacted. |
userAutomations | true | Whether end users may author their own background automations (false ships only builder-registered ones). |
background | false | Whether agent work continues after the window closes. On, end users get a Keep running after I close the window switch (see Automated agents). |
sidePanel | { chat: true, terminal: true, default: "chat" } | Which side-panel tabs ship and which opens first (see Terminal and side panel). |
maxChatsPerAgent | 20 | Chat conversations kept per agent on the user's machine; a new chat past the cap deletes the oldest. 0 means no limit. |
defaultModel | unset | The model a default run uses, as a device selection key (e.g. "claude-code:claude-opus-4.8"). Unset, a fresh chat follows your hosted default and meters credits, exactly like web; set it to a CLI and default runs happen on that user's machine under their own subscription. It is a pointer: users who never chose, and users who reset, follow whatever default your next build ships. |
enabled is a runtime gate, not a packaging one. The runtime is a second entry built from this app's own source (out/main/daemon-entry.js), so every desktop build ships it. Flipping enabled to true in a project generated WITHOUT AI turns the screens on but leaves the engine source out - re-run the CLI (init or update) with --ai to add it.
Where it lives
Chat and Automations are top-level sidebar pages; the AI configuration surfaces are runs of the Settings rail. Each renders only when its own gate is on.
| Surface | Where | Shown when |
|---|---|---|
| Chat | /chat, plus a side-panel tab | the AI surface is on |
| Automations | /automations | the AI surface is on (see Automated agents) |
| Models | Settings | the AI surface is on - the providers, the default model, and the runtime's own controls |
| Tasks | Settings | at least one builder task targets the desktop |
| MCP server | Settings | config.mcpServer is enabled - an authenticated endpoint external agents use to drive the app |
| Integrations | Settings | the AI surface is on and config.ai.enabled - the services users connect their accounts to. An empty catalog shows the empty state, never a hidden entry |
The right side panel carries a Chat tab (the same persisted conversation) and a Terminal tab (the user's own CLI).
What runs, and where
The selected model decides, and it decides per turn.
| Lane | Where it runs | Who pays | Reaches your backend |
|---|---|---|---|
| A hosted model (built-in or the user's own key) | your server, via /ai/chat | your credits, or the user's provider key | yes - metered server-side |
| A connected coding CLI | the user's machine, in a work folder, audited locally | the user's own CLI subscription | tools only - see below |
A coding-CLI chat gets the same app tools the in-app chat has (account data, automations, your own capabilities, and the web tools whenever a search engine is configured): while the user is signed in, the app serves the product's tool manifest to the CLI over a loopback MCP and executes each call on your backend under that user - the AI itself never touches your server. A web_search or web_extract call made there is metered to that user exactly as the same call in web chat is. Each new conversation lists the backend's current manifest, so a tool you add or rename on the server reaches the next new chat without restarting the app.
Four device tools ride that same MCP and need no account at all, because their work happens on the machine:
| Tool | What it does |
|---|---|
list_local_automations | Lists this device's automations, built-ins included. |
create_local_automation | Schedules a new one on this device. |
update_local_automation | Changes one (a built-in takes only its enable flag). |
delete_local_automation | Removes one. |
They are scoped to the active project, and they keep working signed out or with your backend down - which is the whole point: a CLI asked to schedule something locally can comply either way. The backend tools are the half that needs a session, so signed out the chat still works, with the device tools alone.
Automations, per-task overrides and the Terminal are the on-device lane only: fired by the runtime against a CLI, never a hosted model. Automations and the Terminal mount the same app tools a CLI chat does. A running Terminal keeps them when the backend session expires or the project changes: the app renews the session behind the same loopback address. Integrations are the one part that is not on-device: the connection lives in your backend, so the tools it contributes are the ones web chat gets. The app stores no model credential of its own on either lane.
Models
The two model sources, which lane a turn runs on, and who pays.
Tasks
A model and reasoning effort per builder-declared task, chosen per device.
Chat
A persisted, on-device conversation - a full page and a side-panel tab.
Terminal and side panel
Run the user's own CLI in the side panel; choose which tabs ship and which opens first.
Automated agents
Background runs that fire on a timer.
Integrations
The backend-owned service connections users make in-app, shared with the web app.
Updates and downloads
Background auto-updates via electron-updater, the per-OS update feed, and the /download page plus the always-latest installer links behind it.
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.