# 22davidd/project-diana architecture

> Architecture diagram of the GitHub repository 22davidd/project-diana, 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/22davidd/project-diana
- Repository: https://github.com/22davidd/project-diana

## Overview

Project Diana is an offline, continuously running voice-assistant loop. A microphone block enters the main state machine, which routes it to wake detection while idle and to streaming speech recognition after the spoken acknowledgement. The resulting command goes through intent handling: recognized device actions update an in-memory state registry, while unmatched requests may use optional local Ollama chat. The handler’s response returns to the state machine for console or Piper speech output. The map follows README architecture and sampled module contracts; some main-loop wiring is documented but omitted from the source excerpt.

Main entry points: [`diana/main.py`](https://github.com/22davidd/project-diana/blob/main/diana/main.py) (State machine), [`diana/command.py`](https://github.com/22davidd/project-diana/blob/main/diana/command.py) (Command handler), [`diana/speaker.py`](https://github.com/22davidd/project-diana/blob/main/diana/speaker.py) (Speaker interface), [`diana/wakeword.py`](https://github.com/22davidd/project-diana/blob/main/diana/wakeword.py) (Wake detector)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_audio["Audio input"]
  node_audio_source["Audio source<br/>[audio.py]"]
  node_wake["Wake detector<br/>[wakeword.py]"]
  node_stt["Speech recognition<br/>[stt.py]"]
end

subgraph group_conversation["Conversation loop"]
  node_main["State machine<br/>[main.py]"]
  node_config["Configuration<br/>[config.py]"]
end

subgraph group_actions["Command handling"]
  node_handler["Command handler<br/>[command.py]"]
  node_parser["Intent parser<br/>[intents.py]"]
  node_registry[("Device registry<br/>[devices.py]")]
  node_chat["Local chat<br/>[chat.py]"]
end

subgraph group_responses["Response output"]
  node_speaker["Speaker interface<br/>[speaker.py]"]
  node_console["Console output<br/>[speaker.py]"]
  node_piper["Piper speech<br/>[speaker.py]"]
end

node_user(("User"))
node_microphone(("Microphone"))
node_ollama(("Ollama server"))

node_microphone -->|"captures audio"| node_audio_source
node_main -->|"reads blocks"| node_audio_source
node_main -->|"checks wake"| node_wake
node_main -->|"feeds speech"| node_stt
node_wake -->|"signals wake"| node_main
node_stt -->|"returns transcript"| node_main
node_main -->|"handles command"| node_handler
node_handler -->|"parses text"| node_parser
node_parser -->|"checks devices"| node_registry
node_handler -->|"reads or updates"| node_registry
node_handler -.->|"requests fallback"| node_chat
node_chat -.->|"sends prompt"| node_ollama
node_handler -->|"returns response"| node_main
node_main -->|"speaks response"| node_speaker
node_speaker -->|"prints text"| node_console
node_speaker -->|"synthesizes speech"| node_piper
node_piper -->|"plays speech"| node_user
node_console -->|"displays text"| node_user
node_user -->|"speaks"| node_microphone
node_config -->|"configures loop"| node_main

click node_main "https://github.com/22davidd/project-diana/blob/main/diana/main.py"
click node_config "https://github.com/22davidd/project-diana/blob/main/diana/config.py"
click node_audio_source "https://github.com/22davidd/project-diana/blob/main/diana/audio.py"
click node_wake "https://github.com/22davidd/project-diana/blob/main/diana/wakeword.py"
click node_stt "https://github.com/22davidd/project-diana/blob/main/diana/stt.py"
click node_handler "https://github.com/22davidd/project-diana/blob/main/diana/command.py"
click node_parser "https://github.com/22davidd/project-diana/blob/main/diana/intents.py"
click node_registry "https://github.com/22davidd/project-diana/blob/main/diana/devices.py"
click node_chat "https://github.com/22davidd/project-diana/blob/main/diana/chat.py"
click node_speaker "https://github.com/22davidd/project-diana/blob/main/diana/speaker.py"
click node_console "https://github.com/22davidd/project-diana/blob/main/diana/speaker.py"
click node_piper "https://github.com/22davidd/project-diana/blob/main/diana/speaker.py"

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_audio_source,node_wake,node_stt,node_user toneBlue
class node_main,node_config toneAmber
class node_handler,node_parser,node_registry,node_chat,node_ollama toneMint
class node_speaker,node_console,node_piper toneRose
class node_microphone toneIndigo
```

## Components

### Audio input

- [Audio source](https://github.com/22davidd/project-diana/blob/main/diana/audio.py): `diana/audio.py`
- [Wake detector](https://github.com/22davidd/project-diana/blob/main/diana/wakeword.py): `diana/wakeword.py`
- [Speech recognition](https://github.com/22davidd/project-diana/blob/main/diana/stt.py): `diana/stt.py`

### Conversation loop

- [State machine](https://github.com/22davidd/project-diana/blob/main/diana/main.py): `diana/main.py`
- [Configuration](https://github.com/22davidd/project-diana/blob/main/diana/config.py): `diana/config.py`

### Command handling

- [Command handler](https://github.com/22davidd/project-diana/blob/main/diana/command.py): `diana/command.py`
- [Intent parser](https://github.com/22davidd/project-diana/blob/main/diana/intents.py): `diana/intents.py`
- [Device registry](https://github.com/22davidd/project-diana/blob/main/diana/devices.py): `diana/devices.py`
- [Local chat](https://github.com/22davidd/project-diana/blob/main/diana/chat.py): `diana/chat.py`

### Response output

- [Speaker interface](https://github.com/22davidd/project-diana/blob/main/diana/speaker.py): `diana/speaker.py`
- [Console output](https://github.com/22davidd/project-diana/blob/main/diana/speaker.py): `diana/speaker.py`
- [Piper speech](https://github.com/22davidd/project-diana/blob/main/diana/speaker.py): `diana/speaker.py`

### Other components

- **User**
- **Microphone**
- **Ollama server**

## Connections

- Microphone → Audio source: captures audio
- State machine → Audio source: reads blocks
- State machine → Wake detector: checks wake
- State machine → Speech recognition: feeds speech
- Wake detector → State machine: signals wake
- Speech recognition → State machine: returns transcript
- State machine → Command handler: handles command
- Command handler → Intent parser: parses text
- Intent parser → Device registry: checks devices
- Command handler → Device registry: reads or updates
- Command handler → Local chat: requests fallback
- Local chat → Ollama server: sends prompt
- Command handler → State machine: returns response
- State machine → Speaker interface: speaks response
- Speaker interface → Console output: prints text
- Speaker interface → Piper speech: synthesizes speech
- Piper speech → User: plays speech
- Console output → User: displays text
- User → Microphone: speaks
- Configuration → State machine: configures loop
