# kaioh17/ekko architecture

> Architecture diagram of the GitHub repository kaioh17/ekko, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/kaioh17/ekko
- Repository: https://github.com/kaioh17/ekko

## Overview

EKKO is a local-first voice assistant with a desktop control UI. Its documented voice workflow gates command handling through speech detection, wake-word recognition, speaker verification, transcription, closed-set intent matching, and execution; ambiguous requests can use an LLM fallback, with spoken responses. The UI exposes chat, memory, routing, settings, status, and reports through a local authenticated API. Several runtime stages and UI capabilities are documented by the README or tree but their implementation was not sampled, so links are limited to documented behavior and directly evidenced calls.

Main entry points: [`routing/route.py`](https://github.com/kaioh17/ekko/blob/main/routing/route.py) (Route coordination), [`backend/routers`](https://github.com/kaioh17/ekko/tree/main/backend/routers) (API routes), [`backend/main.py`](https://github.com/kaioh17/ekko/blob/main/backend/main.py) (Authenticated API), [`ekko-ui/src/App.tsx`](https://github.com/kaioh17/ekko/blob/main/ekko-ui/src/App.tsx) (Desktop app)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_voice["Voice assistant"]
  node_vad["Speech detection<br/>[vad_listener.py]"]
  node_wake["Wake-word check<br/>[vad_listener.py]"]
  node_verify["Speaker verification<br/>[verify.py]"]
  node_transcribe["Transcription<br/>[vad_listener.py]"]
  node_speech["Spoken feedback<br/>[speech.py]"]
end

subgraph group_routing["Intent routing"]
  node_match["Intent matching<br/>[matcher.py]"]
  node_route["Route coordination<br/>[route.py]"]
  node_execute["Command execution<br/>[execute.py]"]
  node_fallback["LLM fallback"]
  node_routing_config["Routing configuration<br/>[config.py]"]
  node_domain_registry["Domain registry<br/>[domains.py]"]
end

subgraph group_service["API services"]
  node_memory[("Assistant memory")]
  node_backend["Authenticated API<br/>[main.py]"]
  node_routers["API routes"]
  node_status_bus["Status events<br/>[status_bus.py]"]
  node_settings["Assistant settings<br/>[settings.py]"]
end

subgraph group_desktop["Desktop UI"]
  node_app["Desktop app<br/>[App.tsx]"]
  node_client["API client<br/>[client.ts]"]
  node_desktop_controls["Control panels"]
end

subgraph group_integrations["External services"]
  node_gemini(("Gemini API"))
end

node_user(("Owner"))
node_mic(("Microphone"))

node_user -->|"speaks to"| node_mic
node_mic -->|"audio input"| node_vad
node_vad -->|"speech detected"| node_wake
node_wake -->|"wake matches"| node_verify
node_verify -->|"speaker confirmed"| node_transcribe
node_transcribe -->|"transcribed command"| node_route
node_route -->|"checks intent"| node_match
node_match -->|"reads intents"| node_routing_config
node_route -->|"dispatches match"| node_execute
node_route -->|"handles no-match"| node_fallback
node_fallback -.->|"requests completion"| node_gemini
node_route -->|"provides response"| node_speech
node_user -->|"uses"| node_app
node_app -->|"renders panels"| node_desktop_controls
node_app -->|"invokes requests"| node_client
node_client -->|"HTTP requests"| node_backend
node_backend -->|"dispatches routes"| node_routers
node_routers -->|"loads intents"| node_routing_config
node_routers -->|"loads domains"| node_domain_registry
node_routers -->|"serves settings"| node_settings
node_routers -->|"reads and updates"| node_memory
node_backend -->|"publishes status"| node_status_bus

click node_vad "https://github.com/kaioh17/ekko/blob/main/listener/vad_listener.py"
click node_wake "https://github.com/kaioh17/ekko/blob/main/listener/vad_listener.py"
click node_verify "https://github.com/kaioh17/ekko/blob/main/voice_auth/verify.py"
click node_transcribe "https://github.com/kaioh17/ekko/blob/main/listener/vad_listener.py"
click node_match "https://github.com/kaioh17/ekko/blob/main/routing/matcher.py"
click node_route "https://github.com/kaioh17/ekko/blob/main/routing/route.py"
click node_execute "https://github.com/kaioh17/ekko/blob/main/routing/execute.py"
click node_fallback "https://github.com/kaioh17/ekko/tree/main/llm_fallback"
click node_memory "https://github.com/kaioh17/ekko/tree/main/memory"
click node_speech "https://github.com/kaioh17/ekko/blob/main/feedback/speech.py"
click node_app "https://github.com/kaioh17/ekko/blob/main/ekko-ui/src/App.tsx"
click node_client "https://github.com/kaioh17/ekko/blob/main/ekko-ui/src/api/client.ts"
click node_backend "https://github.com/kaioh17/ekko/blob/main/backend/main.py"
click node_routers "https://github.com/kaioh17/ekko/tree/main/backend/routers"
click node_routing_config "https://github.com/kaioh17/ekko/blob/main/routing/config.py"
click node_domain_registry "https://github.com/kaioh17/ekko/blob/main/routing/domains.py"
click node_status_bus "https://github.com/kaioh17/ekko/blob/main/backend/status_bus.py"
click node_settings "https://github.com/kaioh17/ekko/blob/main/backend/routers/settings.py"
click node_desktop_controls "https://github.com/kaioh17/ekko/tree/main/ekko-ui/src/components/panels"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_vad,node_wake,node_verify,node_transcribe,node_speech toneBlue
class node_match,node_route,node_execute,node_fallback,node_routing_config,node_domain_registry toneAmber
class node_memory,node_backend,node_routers,node_status_bus,node_settings toneMint
class node_app,node_client,node_desktop_controls toneRose
class node_gemini,node_user,node_mic toneIndigo
```

## Components

### Voice assistant

- [Speech detection](https://github.com/kaioh17/ekko/blob/main/listener/vad_listener.py): `listener/vad_listener.py`
- [Wake-word check](https://github.com/kaioh17/ekko/blob/main/listener/vad_listener.py): `listener/vad_listener.py`
- [Speaker verification](https://github.com/kaioh17/ekko/blob/main/voice_auth/verify.py): `voice_auth/verify.py`
- [Transcription](https://github.com/kaioh17/ekko/blob/main/listener/vad_listener.py): `listener/vad_listener.py`
- [Spoken feedback](https://github.com/kaioh17/ekko/blob/main/feedback/speech.py): `feedback/speech.py`

### Intent routing

- [Intent matching](https://github.com/kaioh17/ekko/blob/main/routing/matcher.py): `routing/matcher.py`
- [Route coordination](https://github.com/kaioh17/ekko/blob/main/routing/route.py): `routing/route.py`
- [Command execution](https://github.com/kaioh17/ekko/blob/main/routing/execute.py): `routing/execute.py`
- [LLM fallback](https://github.com/kaioh17/ekko/tree/main/llm_fallback): `llm_fallback`
- [Routing configuration](https://github.com/kaioh17/ekko/blob/main/routing/config.py): `routing/config.py`
- [Domain registry](https://github.com/kaioh17/ekko/blob/main/routing/domains.py): `routing/domains.py`

### API services

- [Assistant memory](https://github.com/kaioh17/ekko/tree/main/memory): `memory`
- [Authenticated API](https://github.com/kaioh17/ekko/blob/main/backend/main.py): `backend/main.py`
- [API routes](https://github.com/kaioh17/ekko/tree/main/backend/routers): `backend/routers`
- [Status events](https://github.com/kaioh17/ekko/blob/main/backend/status_bus.py): `backend/status_bus.py`
- [Assistant settings](https://github.com/kaioh17/ekko/blob/main/backend/routers/settings.py): `backend/routers/settings.py`

### Desktop UI

- [Desktop app](https://github.com/kaioh17/ekko/blob/main/ekko-ui/src/App.tsx): `ekko-ui/src/App.tsx`
- [API client](https://github.com/kaioh17/ekko/blob/main/ekko-ui/src/api/client.ts): `ekko-ui/src/api/client.ts`
- [Control panels](https://github.com/kaioh17/ekko/tree/main/ekko-ui/src/components/panels): `ekko-ui/src/components/panels`

### External services

- **Gemini API**

### Other components

- **Owner**
- **Microphone**

## Connections

- Owner → Microphone: speaks to
- Microphone → Speech detection: audio input
- Speech detection → Wake-word check: speech detected
- Wake-word check → Speaker verification: wake matches
- Speaker verification → Transcription: speaker confirmed
- Transcription → Route coordination: transcribed command
- Route coordination → Intent matching: checks intent
- Intent matching → Routing configuration: reads intents
- Route coordination → Command execution: dispatches match
- Route coordination → LLM fallback: handles no-match
- LLM fallback → Gemini API: requests completion
- Route coordination → Spoken feedback: provides response
- Owner → Desktop app: uses
- Desktop app → Control panels: renders panels
- Desktop app → API client: invokes requests
- API client → Authenticated API: HTTP requests
- Authenticated API → API routes: dispatches routes
- API routes → Routing configuration: loads intents
- API routes → Domain registry: loads domains
- API routes → Assistant settings: serves settings
- API routes → Assistant memory: reads and updates
- Authenticated API → Status events: publishes status
