BMO
A physical AI assistant inspired by BMO from Adventure Time: a face on a touchscreen, a voice, a local LLM, control of the house and a 3D-printed case. Built from scratch to take AI out of the browser and into a room.
Talk to its core
BMO's core publishes a state and the face decides how to draw it. This is the same expression model the real UI uses.
Publish a state to BMO's core
bmo/state"IDLE"
Two machines
BMO Core
Raspberry Pi 5, always on
Python core, state machine, UI and MQTT broker. Home Assistant comes next.
AI Server
Desktop with an RTX 4060, on demand
Ollama, heavier models and speech-to-text on the GPU.
Decisions that shaped it
- State is separate from its representation.
- The core publishes "thinking"; the UI decides what thinking looks like.
- The LLM proposes, tools execute.
- The model returns a structured intent. It never touches a device directly.
- A missing GPU is a state, not a crash.
- If the AI server is off, BMO still boots, shows its face and says so.
- Audio never touches the disk.
- It lives in memory for one turn, travels over TLS inside the LAN, then is dropped.
Where it stands
- Voice loop
- Wake → Whisper → core → Piper, with a DSP "BMO" effect
- Messaging
- MQTT with retained state, ACLs and TLS
- Face
- Drawn by code at 60 fps from a JSON of expressions
- Decisions
- Every one written down as an ADR, rejected ones included
First voice loop measured at 3.7–6.3 s end to end on CPU. The GPU path is next.