Introduction
FRIDAY started as a question: what would a voice assistant look like if it actually lived on your machine, knew your context, and could execute multi-step CLI work without ever crossing a network boundary? The product is a locally-running AI agent featuring multi-layer routing, persistent memory, and autonomous task execution through an MCP-standardized tool surface.
The problem with cloud-bound assistants
Existing voice assistants rely heavily on cloud compute and treat the desktop as a microphone for someone else's API. They cannot execute complex, multi-step CLI operations, do not retain procedural memory across sessions, and have no concept of the local filesystem or shell. For a Linux power-user, that is the inverse of useful.
An assistant that lives on the machine should know the machine — its files, its shell, its history. Anything less is a hotline to a server.
Architecture
I engineered a three-tier routing architecture — deterministic execution for known intents, LLM tool selection for ambiguous ones, and a conversational fallback when neither applies. On top of that sits the TaskGraphExecutor: a planner that computes topological waves of tool dependencies, enabling parallel execution of independent tasks instead of the standard sequential agent loop.
Persistent memory is split into three layers — episodic events go to SQLite, semantic facts to ChromaDB with embeddings, and procedural sequences are surfaced as MCP tools the agent can re-invoke. The result is an assistant that gets faster the longer you use it, because every successful task becomes a primitive for the next one.
What I prioritized
A few of the technical decisions that mattered most:
- Three-tier memory. Episodic, semantic, and procedural memory utilizing SQLite and ChromaDB.
- Parallel execution. TaskGraphExecutor runs independent tools simultaneously in topological waves.
- 50+ integrations. Browser automation via Playwright, Google Workspace, and arbitrary shell tooling.
- Local-first. Zero cloud dependencies. Every byte of memory stays on the user's filesystem.


