BMO

BMO

A tiny desk companion with a face, a voice, a memory core, and five little buttons that make the hardware feel alive.

Spin it in 3D & print it yourself on a Bambu Lab A1
Signal quest1/5

See it in action

BMO, listening and talking back.

A quick clip of the push-to-talk loop: hold the touch sensor, speak, release — and BMO answers out loud with a live lip-sync face.

A bright circuit-board meadow with button flowers and glowing solder pads.

Playable information

Every button teaches one part of the build.

Touch the controls, watch the face answer, then scroll into the little body to see which organ does the work.

Feature map

What the tiny toy actually does.

The landing is cute, but the build is practical: each interaction is a visible state backed by a real hardware or software role.

Firmware renderer

Expression engine

The firmware owns the face library: idle, touch, listen, thinking, talking, laughing, bashful, and the wider mood set.

User sees
BMO blinks, glances, smiles, talks, reacts to touch, and never feels like a static image.
How it works
A 160x128 RGB565 back-buffer is composed around 30 fps and flushed over hardware SPI.
TTP223 + touch classifier

Touch language

One capacitive pad becomes several gestures instead of a single boring button press.

User sees
Tap gives a small surprise, hold opens listening, long-hold gets shy, and rapid taps can become a laugh moment.
How it works
The firmware debounces the touch line, classifies press timing, and maps it to mood plus audio behavior.
INMP441, brain API, MAX98357A

Voice loop

BMO moves from listening to thinking to talking, so voice input has a visible status at every step — and the talking mouth lip-syncs to the reply.

User sees
The face shows a glitchy listening state while recording, a pulsing thinking orb during the round-trip, and a lip-synced mouth while the reply plays.
How it works
Held-touch captures auto-gained low-rate mono audio (decimated so a fixed buffer holds ~6s) sent to the brain route; streamed PCM16 feeds the I2S speaker while a live envelope drives the mouth.
Audio clips + voice service

Tiny voice pack

Short local clips keep instant reactions fast, while streamed replies cover open conversation.

User sees
BMO greets you instantly (and lip-syncs) on a normal touch, and still speaks longer generated replies when the brain route answers.
How it works
Greetings are generated once in BMO’s real voice, downsampled, and baked as 4-bit ADPCM into firmware; generated replies stream to avoid storing large audio.
Brain service + Supabase memory

Memory core

A gbrain-inspired layer gives BMO short-term conversation continuity plus a durable, self-updating profile of the child.

User sees
Follow-ups make sense (apple → “red” stays on topic), and BMO remembers the child’s name — learned, never hardcoded, newest value wins.
How it works
Recent turns are replayed as chat history; stable facts are upserted by key and recalled by vector similarity before each reply. Fully degradable.
Brain route + OpenRouter web plugin

Live web search

For questions that depend on current facts, BMO can look things up on the web instead of guessing from stale training data.

User sees
Ask "who is the president now" or "what is the weather today" and BMO answers from fresh results, not an out-of-date memory.
How it works
When the web_search skill is on, the brain call enables the OpenRouter web plugin and nudges the model to trust live results; citations and URLs are stripped before the reply is spoken.
Soul editor + brain route

Editable personality

BMO’s persona, tone, and reply language all come from one editable soul prompt — the single source of truth.

User sees
Change the soul on the dashboard to make BMO talk differently or reply in another language; it takes effect on the next request.
How it works
The brain route sends the soul verbatim as the system prompt (plus only the live clock). No hardcoded language or style clamp overrides it.
Fingerprint guard

Secure cloud bridge

The device can talk to the cloud brain without making the private operator controls public.

User sees
A paired BMO can call the brain route; an unpaired request gets rejected.
How it works
Firmware sends an X-BMO-Fingerprint header while the server stores only the hashed value.
Supabase login + Next.js route

Private operator console

The public homepage explains the build, while the admin controls stay intentionally unlisted.

User sees
Visitors see the landing and wiki; the operator still has a private route for tuning the device.
How it works
The operator route remains behind Supabase login and is excluded from public navigation and sitemap.
BMO-ESP32 repo

Open build kit

The project is meant to be hackable: firmware, voice tools, wiring notes, and the web brain live in the repo.

User sees
A builder can inspect the code, flash the device, replace clips, and iterate on the shell.
How it works
PlatformIO handles firmware flashing; Next.js, Supabase, and small scripts handle the cloud side.

Inside BMO

Real hardware, cast as tiny organs.

The screen is the feeling window. The ESP32-C3 is the pocket brain. The mic, speaker, touch pad, and memory core each get a visible role, so the device reads as a character instead of a box of parts.

Read the build wiki
A mint-green open console showing whimsical hardware organs inside.Feeling WindowRounded TFT faceeyes, glances, and mouth shapesPocket BrainESP32-C3Wi-Fi, timing, mood stateListening SproutI2S microphonevoice awarenessVoice StarTiny speakersmall voice outputKind ButtonTouch sensortap, hold, long-holdWonder HeartMemory coreGBrain-inspired recall

3D preview · Bambu Lab A1

See it in 3D. Then print your own.

This is the real, printable BMO — straight from the build files. Switch between the assembled body and the two A1 print plates, then orbit with the Front / Back / Left / Right / Top / Bottom buttons. Everything is sized for a Bambu Lab A1 (256 × 256 mm bed).

  1. ExploreSpin the model above. Tap a part to learn its job. Pick the Outside or Inside kit to see how it all packs in.
  2. DownloadGrab the A1-ready plates below (.3mf), already laid out flat with zero overlap. STL is in the repo if you prefer.
  3. Print on your A1Open the .3mf in Bambu Studio, pick PLA, slice, and send to your Bambu Lab A1. ~2 plates, no supports for the body.

Components needed

The build checklist.

Pocket Brain

ESP32-C3

Runs timing, Wi-Fi, mood state, button handling, and the route to the brain service.

Need
ESP32-C3 Super Mini board
Wire / route
Owns TFT SPI, I2S audio, touch input, Wi-Fi, and firmware secrets.
Note
Target PlatformIO env: esp32c3_supermini.
Feeling Window

ST7735 TFT display

Shows eyes, mouth shapes, glances, listening, thinking, talking, bashful, and the wider mood set.

Need
1.8 inch 160x128 RGB565 ST7735 display
Wire / route
CS GP7, RESET GP10, DC GP3, MOSI GP6, SCK GP4; VCC and LED to 3V3.
Note
The face is rendered in a small double-buffered framebuffer.
Listening Sprout

I2S microphone

Makes the listening state real and gives the firmware a voice-input path.

Need
INMP441 I2S microphone
Wire / route
Shares the ESP32-C3 I2S clock (GP0/GP1); data (SD) on GP5.
Note
SD must avoid strapping pins GP8/GP9, or capture reads as silence.
Voice Star

I2S amp + speaker

Plays compact voice output and lets talk animation follow the reply rhythm.

Need
MAX98357A I2S amp plus 8 ohm 1 W speaker
Wire / route
BCLK GP0, LRC GP1, DOUT GP2; speaker connects to amp output pads.
Note
Short clips are instant; streamed PCM16 replies come from the brain route.
Kind Button

Touch sensor

Turns tap, hold, and long-hold into distinct personality inputs.

Need
TTP223 capacitive touch sensor
Wire / route
Touch output to GP20, plus VCC and GND.
Note
The top touch pad is the main physical interaction.
Wonder Heart

Memory service

Stores preferences, recent moments, and context for more coherent behavior.

Need
Next.js brain routes with Supabase-backed memory
Wire / route
ESP32 posts to the deployed origin with its fingerprint header.
Note
Inspired by Garry Tan GBrain-style recall and enrichment.
Stage

Power and wiring

Keeps the tiny cast stable enough that animation and audio do not brown out.

Need
USB-C data cable, 3V3/GND bundles, jumpers, and a reliable 1 A supply
Wire / route
Display, mic, touch, amp, and board share planned power and ground rails.
Note
Build one subsystem at a time so wiring bugs are easy to isolate.

Core brain

Small enough for the desk, thoughtful enough to remember.

The project keeps the public magic playful while the memory idea nods to Garry Tan's GBrain: moments become preferences, synthesis, and useful gaps.

capture + brain-first recall

Persistent memory

Every exchange is embedded and written down, then recalled by meaning before BMO answers — so follow-ups stay on topic and the brain grows the more BMO is used.

lib/brain.ts · match_brain_memory
think (synthesis + gap analysis)

Reasoned recall

Beyond fetching memories, BMO can compose a single cited answer and honestly flag what it does not know yet.

lib/brain/synthesize.ts
self-wiring knowledge graph + enrich

Connected memories

People, places, and topics become entities with typed links, so BMO can reach facts that plain similarity search misses.

lib/brain/graph.ts · entities.ts
enrich the entity over time

Child profile

Durable facts about the child (name, favorites, fears) are distilled from conversations and updated in place — learned, never hardcoded, newest value wins.

lib/brain/profile.ts
salience + dedup

Importance & tidy-up

Memories are scored for importance and near-duplicates are found, so what matters is kept and clutter is pruned.

lib/brain/salience.ts
24/7 dream cycle (maintain)

Dream cycle

A scheduled offline pass consolidates, de-duplicates, and re-scores memory so recall quality improves over time with no human in the loop.

lib/brain/consolidate.ts · /api/brain/dream
find_trajectory / timeline

Timeline

A temporal view of memory — what happened, in what order, and how a topic evolved across time.

lib/brain/timeline.ts
hybrid search

Hybrid search

Vector similarity and keyword search are fused with reciprocal-rank fusion for results that beat either signal alone.

lib/brain/search.ts
gbrain doctor / skillpack-check

Brain health

Built-in checks (table reachable, memories present, embeddings present, recall working) roll up into a single health score.

lib/brain/doctor.ts
dream-cycle idea, applied to a toy

Random thoughts

When played with, BMO thinks out loud on its own: it recalls what it knows, muses one short line in its own voice, speaks it, and remembers the thought — a self-feeding inner life. gbrain has no named skill for this; it is their dream-cycle idea made spontaneous.

lib/thoughts.ts · /api/brain/idle-thought