-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture
Chris Schroedinger edited this page Jul 3, 2026
·
1 revision
For the full design document with rationale, see DESIGN.md in the repository. This page is the short version.
┌─────────────────────────────────────────────────┐
│ agentwhisperd (the daemon) │
│ │
│ hotkey listener ─▶ state machine ─▶ engine │
│ (XGrabKey) (debounced) (whisper) │
│ │ │ │ │
│ audio capture DesktopBackend (X11): │
│ (sounddevice) type / clipboard / notify │
│ │
│ IPC: unix socket, JSON-lines protocol │
└───────▲──────────────▲──────────────────────────┘
│ │
agentwhisper tray icon + menu
CLI (GTK/AppIndicator)
- The daemon owns all state: hotkey, microphone, model, recording lifecycle. Binding its socket doubles as the single-instance lock — a second launch says "already running" and exits.
- The tray and the CLI are clients. A broken tray can never take dictation down.
- No silent failures. Every integration (GTK bindings, desktop tools, model, hotkey grab) is verified at startup; every error message contains its fix.
- Pure-logic core. The recording state machine has no I/O — the debounce against X11 key auto-repeat is fully unit-tested.
-
Interfaces at the boundaries.
Engine(speech-to-text) andDesktopBackend(typing/clipboard/notifications) are small protocols. Wayland support or a cloud engine are new modules, not rewrites. - Text is never lost. Clipboard first, then typing — if typing fails, the notification says the text is in the clipboard.
| Module | Responsibility |
|---|---|
daemon.py |
Wires everything; IPC server; lifecycle |
state.py |
Recording state machine (pure logic, debounce) |
hotkey.py |
Exclusive key grab via X11 XGrabKey |
audio.py |
Microphone capture + live level (sounddevice) |
engines/ |
Engine protocol + faster-whisper implementation |
desktop/ |
DesktopBackend protocol + X11 implementation |
tray.py |
Tray icon and menu (GTK/AyatanaAppIndicator) |
visualizer.py |
The recording OSD with the level bars |
cli.py, ipc.py
|
Client commands and the socket protocol |
config.py |
TOML config, strict validation |
./install.sh # environment (system Python + GTK bindings)
uv run pytest # 53 tests
uv run ruff check .Tests cover the state machine (including a simulated X11 auto-repeat storm), config validation, the IPC protocol, and the full record→transcribe→deliver pipeline with fake hardware.
AgentWhisper