Clone and build from source
Esta página aún no está disponible en tu idioma.
This page is for people who keep a checkout of the repository: contributors, plugin authors, and anyone who wants to read the code before running it. The instructions below are for Linux; the macOS side is covered in macOS.
git clone https://github.com/sujaisubbanna/utter-assistant.gitcd utter-assistantThe wizard from a checkout
Section titled “The wizard from a checkout”The same wizard as the remote installer runs from the repository root:
./install.sh --dry-run # walk the wizard, print the plan, change nothing./install.sh # install the components you choose./install.sh --uninstall # undo itThe developer installer
Section titled “The developer installer”install/install.sh is the minimal alternative: distro packages and the runner service, nothing
else. By default it only prints what it would do.
install/install.sh --dry-run # default: print exactly what it would doinstall/install.sh --yes # actually install deps + enable the runner unitinstall/install.sh --yes --no-deps # skip distro packages, only wire the serviceWhat it does:
- Detects the distro from
/etc/os-release(IDandID_LIKE) and picks pacman, apt, dnf or zypper (falling back tocommand -v). - Installs the system dependencies, name-mapped per distro:
wtype,ydotool(andydotoold),grim,wl-clipboard,pipewire,webkit2gtk-4.1andlibsoup-3.0for the Tauri settings app, and optionallykeyd. AT-SPI accessibility (python-gobject+at-spi2-core) is optional and degrades gracefully. - Checks the
inputgroup and/dev/uinput, and prints theusermod -aG input, udev and re-login steps. It never silently changes groups. - Installs and, with
--yes, enables the user serviceutter-runner.service, bound to the graphical session via thescripts/utter-wayland-ready.shwrapper. - Records what it did in
$XDG_STATE_HOME/utter/install.jsonso it can be reversed. - Runs
python -m assistant doctor --json(orrecommend --json) to verify.
Uninstall:
install/uninstall.sh --dry-runinstall/uninstall.sh --yes # stop/disable units, remove recorded filesinstall/uninstall.sh --yes --purge # also remove models + configPackage removals are printed, never performed automatically.
Services
Section titled “Services”The runner is a systemd user unit. User services do not inherit the session environment, so
the unit runs through scripts/utter-wayland-ready.sh, which discovers WAYLAND_DISPLAY,
DBUS_SESSION_BUS_ADDRESS and NIRI_SOCKET before starting the runner.
| Unit | Purpose |
|---|---|
utter-runner | the modular runner (plugin supervisor), installed by the installer |
utter-bridge | legacy Python assistant (voice→action), for older installs |
utter-vision | vLLM UI-TARS grounding server (:8000) |
utter-planner | vLLM planner (:8001) |
utter-audio-defaults | keeps the chosen output and denoised input pinned |
Only the runner unit (and the legacy utter.service plus ydotoold.service) ship in the
repository. The vision, planner and audio-defaults units are conveniences on the reference
machine; the scripts they wrap (scripts/serve_vision.sh, scripts/serve_planner.sh,
scripts/utter-audio-defaults.sh) are in the repo, and you can turn them into units yourself.
See Configuration for the shipped unit files.
systemctl --user status utter-runner.servicejournalctl --user -u utter-runner.service -fClients such as the settings app and the Noctalia widget connect to the runner at
$XDG_RUNTIME_DIR/utter/runner.sock.
The assistant CLI
Section titled “The assistant CLI”python -m assistant doctor [--json] # deps + plugin negotiation + driftpython -m assistant recommend [--json] # hardware-aware profile suggestionspython -m assistant models list|show <n>|pull <src>|rm <n>|prune [--json]python -m assistant status [--json] # runner.status passthroughpython -m assistant install-state record|showdoctor --json includes a deps section (which CLI tools and libraries are present) alongside,
per plugin, the negotiated protocol version, unknown capabilities, missing requirements and the
list of permissions with whether each is enforced or advisory. The full command reference is on
The assistant CLI.
The model store
Section titled “The model store”Models live in an Ollama-style, XDG-compliant store:
$XDG_DATA_HOME/utter/models/ # override with UTTER_MODELS manifests/<host>/<ns>/<name>/<tag>.json blobs/sha256-<hex>- Sources:
hf:org/repo[:file]resolves to the Hugging Faceresolve/mainURL; barehttps://URLs and localfile://paths also work. - Pulls are resumable (partial file plus
curl -C -, or urllibRange), with retry and backoff, SHA-256 verification, an atomic rename, a pull lock and a disk-space preflight. rmdrops the manifest and any now-unreferenced blobs;prunecollects orphans.
Models are your choice. The installer never downloads one. assistant recommend suggests a
profile for your GPU and RAM; you pull what you want. See the Models guide.
Running the core from the checkout
Section titled “Running the core from the checkout”The assistant core is stdlib-only Python, so you can run it directly:
# route a command without executing it (prints the plan)python3 -m utter.daemon --text "open youtube" --dry-run
# the full verification: runner unit tests, socket e2e, conformancescripts/verify.shThe dry run is the fastest way to check what a phrase would do. The utter_py plugin defaults
UTTER_DRY_RUN to on, so only UTTER_DRY_RUN=0 touches the desktop.
Building the settings app
Section titled “Building the settings app”The settings app is Tauri v2 + React + Tailwind CSS v4. It needs Rust 1.90+, Node 22+ with
pnpm, and the webkit2gtk-4.1 and libsoup-3.0 libraries.
cd gui-tauripnpm installpnpm tauri build # release binary + .deb in src-tauri/target/release[/bundle]pnpm tauri dev # dev mode with hot reloadFor a quick binary without bundling:
pnpm build # frontend -> dist/cd src-tauricargo build --release --features custom-protocolThe custom-protocol feature embeds the built frontend. Without it, Tauri treats the build as
dev and expects the Vite server on http://localhost:1420.
Run a built binary directly:
WEBKIT_DISABLE_DMABUF_RENDERER=1 ./src-tauri/target/release/utterTwo environment variables help with screenshots and testing: UTTER_GUI_ROUTE (for example
voice) forces the initial page and UTTER_GUI_THEME (light, dark or system) forces the
theme.
Optional: the Noctalia widget
Section titled “Optional: the Noctalia widget”If you run the Noctalia shell, there is an optional widget package at widgets/noctalia/
(bar widget, persistent attention panel and assistant OSD). It is not installed by default.
widgets/noctalia/install.sh # copy + lintwidgets/noctalia/install.sh --yes # + enable and add the bar widget./install.sh --with-noctalia # via the main installerSkip it entirely if you do not use Noctalia. The core assistant does not depend on it. See Noctalia widget and OSD.
Writing a plugin?
Section titled “Writing a plugin?”Start from plugins/fake_py/ (Python) or plugins/fake_rs/ (Rust) and read
Writing a plugin.