AI
Chat and automations inside the mobile app - the shared backend binding, the model picker, attachments, voice input, background behavior, and what the app never runs.
The app's AI surfaces appear when config.ai.enabled. They call the same /ai/* routes the website uses and share their controller through @repo/app-core, so a fix lands on both surfaces at once.
With the flag off the tab button is hidden and every AI route redirects home, so a deep link to a chat or an automation never lands on an empty screen. Automations carries no tab button at all and is reached by navigation.
Chat
| Piece | Where it lives |
|---|---|
| Transport and message state | @repo/app-core - the same chat controller the web chat mounts |
| Model, reasoning level and web-search preferences | The device's own key-value store, through lib/chat/seams.ts |
| The model picker's options | GET /ai/models, the backend's own registry |
| Screens | apps/mobile/app/(app)/chat |
The Chat tab opens a conversation, not the list: the last one open in this workspace, or a new one when there is none. The list is at /chat/list, reached from a conversation's own history control; a conversation also carries a new-chat control.
Credits, plan limits and the model registry are the backend's, so a mobile turn costs and behaves like its web equivalent - see AI.
The picker offers built-in models only - the platform:: keys GET /ai/models serves, billed from credits. Bring-your-own-key is a web surface; the app ships no key-management screens.
Attachments
| Source | Notes |
|---|---|
| Camera | Captured, downscaled on device, then uploaded. |
| Photo library | The same image policy and caps as the web app. |
| Files | Documents, subject to the shared per-message counts and size caps - see AI. |
Images are resized before upload, so a modern phone photo never spends a full-resolution image's tokens. The sheet offers only the sources the active model accepts, so a model that reads photos but no PDFs shows no file source.
Voice input
Dictation runs through expo-speech-recognition. The mic button is hidden unless the device reports recognition available, so a build or a device without it renders no dead control rather than failing on tap.
Recognition may run on-device or through the platform's own service, depending on the device. Say which in your privacy policy.
Background behavior
A streaming answer stops when the app leaves the foreground and does not resume - there are no resumable streams. Automations are the supported way to get work done while the app is closed.
Automations
The app lists automations, opens one, runs it now, and enables or disables it. There is no authoring form on the phone: choosing a lane, a model and a cadence stays on the web app.
Automations fire server-side on the backend's own five-minute sweep, so they run with the app closed, bill the workspace owner in credits, and never execute on the device. A definition that runs on a member's own machine gets neither control here, because a phone cannot start it.