← back

the session player

Otto

A local-first AI agent harness for Apple Silicon: a background daemon that runs coding personas over local models — cloud only when you say so — with a terminal CLI, a native Mac app and a web dashboard all attached to the same durable sessions at once.

Python macOS local-first three clients

One daemon owns everything — sessions, personas, provider access — and the clients are thin views that attach and detach without disturbing work already in flight. Close the terminal mid-turn and the turn keeps going; open the Mac app and the dashboard and all three converge on the same state. That state is an append-only entry tree in SQLite where messages, tool calls and config changes are all just entries, so rollback is moving a leaf pointer and crash recovery falls out of the same log.

A persona is a role, a model profile describes how to talk to one model, and effort scales thinking budget and per-turn tool allowances. MLX models route to oMLX, GGUF models to llama.cpp or Ollama, and any persona can bind to any model on any backend — a cloud lead can delegate to local coders, or a fully local session can send only its search queries out. Nothing reaches a cloud provider without a deliberately cloud-enabled persona or an explicit approval recorded as a durable audit entry; there is no silent local-to-cloud fallback.

The terminal is the main instrument: a full-screen app with a multi-line composer, slash-command and @file menus, markdown replies, coloured diffs, collapsible tool calls, nine views a keystroke apart, and an honest cost readout that says "$0.00 local" when every token was. Shell commands aren't sandboxed and the trust model says so plainly — instead there are ask-by-default approvals, workspace-confined file tools, private git checkpoints with preview-gated rollback, and secret redaction wherever text becomes durable. Also a disco-ball pet that dances while Otto works and dozes off when it doesn't.

highlights

daemon

one daemon, three clients

A terminal CLI, a native Mac app and a loopback web dashboard attach simultaneously and converge on the same durable state. Detaching never interrupts a turn.

log

append-only sessions

Messages, tool calls and config changes are all entries in SQLite — so branching, rollback and crash recovery come from one mechanism instead of three.

models

local first, cloud on request

MLX through oMLX, GGUF through llama.cpp or Ollama, plus Anthropic, OpenAI and Gemini — with API keys living only in the macOS Keychain.

egress

nothing leaves silently

Content goes to a cloud provider only for a cloud-enabled persona or after an explicit approval, and the approval itself is written into the session log.

rails

checkpoints, not promises

Private git checkpoints with preview-gated rollback, ask-by-default shell approvals, workspace-confined file tools, and secret redaction before anything persists.

terminal

a real TUI

Multi-line composer, slash and @file completion, coloured diffs, collapsible tool calls, five palettes — and a status-line pet that naps between turns.

under the hood