# desktop-assistant A local text assistant daemon. Questions arrive on a Unix socket, the model already loaded in a local llama-server answers, calling read-only tools when a question needs them, and the reply streams back token by token. Every conversation is kept in a local SQLite history with full-text search. The model and the history stay on the machine; only tools you enable (weather, web search) reach the network. The front end is the assistant canvas of the quickshell desktop (`desktop/assistant/` in the quickshell repo, on SUPER+Home). Anything that speaks JSON lines on a Unix socket can drive it. The voice version (push-to-talk, whisper, Kokoro) is the tag `voice-v1`. ## Requirements - a running `llama-server` with an OpenAI-compatible API, router mode - Python 3 (stdlib only; SQLite with FTS5) - `curl` and `jq` for the weather and search example tools, `python3-dateutil` for the calendar one ## Usage ```sh python3 assistant.py # run python3 assistant.py --test # self-check ./assistant.sh start # detached ./assistant.sh stop ./assistant.sh restart ./assistant.sh status ``` The daemon uses whichever model the router has loaded, so it never swaps a model out under another client. Only one daemon serves the socket: a second one refuses to start while the first answers. ## Protocol JSON lines both ways on `$XDG_RUNTIME_DIR/desktop-assistant.sock` (mode 0600). Every connected client sees every event. In: `ask {text}`, `stop`, `new`, `list`, `open {id}`, `search {q}`, `delete {id}`. Out: `hello` on connect (state, model, context use, the current conversation and any reply in flight), then `user`, `think`, `token`, `tool`, `done`, `state`, `ctx`, `error`, and the answers `conversations`, `conversation` and `results`. The full table is in `docs/superpowers/specs/2026-10-16-text-daemon-design.md`. Ids are integers; a malformed command or argument answers `error` and the connection stays open. Try it by hand: ```sh socat - UNIX-CONNECT:$XDG_RUNTIME_DIR/desktop-assistant.sock {"type":"ask","text":"What time is it?"} ``` ## History `~/.local/share/desktop-assistant/history.db` (`$XDG_DATA_HOME` honoured), directory 0700, file 0600. The model is sent the last 10 turns of the open conversation. Tool results are stored as a placeholder, not their output. Reasoning is shown live and not stored. ## Configuration and tools Everything is optional. Settings and tools live in `~/.config/desktop-assistant/` (or `$XDG_CONFIG_HOME/desktop-assistant/`): ```sh mkdir -p ~/.config/desktop-assistant cp examples/config.toml ~/.config/desktop-assistant/ cp -r examples/tools ~/.config/desktop-assistant/ ``` - `config.toml`: every key is optional, the example lists the defaults. `[env]` is added to every tool's environment; put instance URLs and key file paths there. - `tools/.toml`: one tool each, enabled by being there. A tool is a command run without a shell, its stdout goes back to the model: ```toml description = "What the tool does, for the model" command = ["script.sh", "{param}"] # looked up in tools/ first, then PATH timeout = 10 [params.param] type = "string" description = "What the model should pass" ``` The example tools only read: - `now`: date and time - `calendar`: `agenda.py` over a vdirsyncer folder - `weather`: OpenWeatherMap, key file in the conky-theme-udt format - `search`: a SearXNG instance with the JSON format enabled - `calc`: `qalc` (arithmetic, units, currencies, date math) - `mail`: unread threads through `mailctl` searches, no tagging or sync - `playing`: the current track from `playerctl`, or `mpc` - `finance`: balances, budgets and spending from Firefly III's `firefly` list commands - `bluetooth`: power, connected devices (battery when reported) and paired ones, through `bluetoothctl show/devices/info` - `vms`: libvirt VMs and their state, or one VM's details, through `virsh` read commands - `updates`: Slackware -current ChangeLog entries newer than the installed packages: counts, security fixes, kernel bump, one package's notes, or a full markdown recap opened in `MD_EDITOR` (default `xdg-open`); `CHANGELOG` and `PKGDIR` in `[env]` override the mirror path and package database ## License Copyright (C) 2026 Danilo M. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. See [LICENSE](LICENSE). ## Development Approach This project is developed using AI-assisted tools. Code is generated with the help of AI based on human-provided specifications, design decisions, and iterative feedback. All contributions are reviewed, tested, and curated by the maintainer before being included in the codebase. AI is used as a productivity and exploration tool, while human oversight remains central to all decisions. The goal is to combine the flexibility of AI-assisted development with standard open-source practices such as transparency, review, and accountability.