DEV Community

Attila Reterics
Attila Reterics

Posted on

Hey Mirae, continue our story

Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission 🦥

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady

What I Built

Mirae is a small Raspberry Pi 5 companion robot I'm designing, and this week I gave it one job that rewards being lazy: it tells you one continuing story, a new episode every night.

Most AI stories are one-shots. You ask, you get a tale, and by morning it's gone. Mirae tells a series. Every night it writes the next episode of the same story, beginning where the last one ended. A captain introduced on night one is still the captain on night thirty. A stranger who joins on night two is still aboard on night nine. A character who dies stays dead. You never recap, never remind it who is who, never keep notes. Mirae keeps the notebook for you.

Setting it up takes about a minute: choose a genre, write a one-line premise, name your characters. After that there is nothing left to do but ask, and fall asleep.

Who gets to be lazier? Anyone who wants a story at the end of the day without inventing one, scrolling for one, or keeping track of the plot themselves.

Demo

The film starts with the experience and ends with the real dashboard:

  • The bedroom and story-world shots are concept visualizations, generated with Higgsfield from Mirae's CAD renders. The physical robot is not built yet; I checked every robot shot against the renders so the design never drifts.
  • The story text is real. Night 2 in the film ("Kael" calling the cargo ship) is exactly what Gemma 4 wrote in my test run, and the "Kael joined the cast" update is the real dashboard after that night.
  • Honest gap: in the film she asks "Hey Mirae, continue our story." Today you press Tell tonight's episode on the dashboard (or call the API). Speech recognition already runs locally with faster-whisper, but wiring it to the story is next.

Code

Mirae logo: the Mirae robot

Mirae

Simple body. Intelligent behavior.
A small, open and hackable AI companion robot built around a Raspberry Pi 5

Build status Website: reterics.github.io/Mirae Status: early prototype Raspberry Pi 5

Mirae, a small white and charcoal robot with two softly glowing eyes, on a wooden floor in a sunlit living room

Rendered from the exact printable model in cad/; no AI image generation.

Open the website Download the STL files Download the shopping cart

Five parts, each fits a 220 × 220 bed · Shopping cart: HESTORE cart export (XML), about 22 600 Ft net, see the full parts list


Meet Mirae

Mirae is a two-wheeled companion that lives on your floor. It sees you, hears you and answers you, but it doesn't try to look human. There's no mouth, no ears and no cartoon face: just a soft rounded body, two diffused light points for eyes, and a front panel that can later become a screen.

Its personality comes from software rather than mechanics. Computer vision, speech recognition and a pluggable AI layer run on a Raspberry Pi 5. The body around them is fully 3D-printable on an ordinary 220 ×…




Repository: github.com/Reterics/Mirae

The story feature lives in src/mirae/story/ (state, prompts, continuity rules), the voice in src/mirae/speech/, and the dashboard page in src/mirae/admin/story-ui.js.

How I Built It

Open-weight model, local inference. Every episode is written by Gemma 4 (12B) running locally through Ollama. Mirae talks to any OpenAI-compatible endpoint, so the model can run on the robot, a home server or a desktop. An episode of about 350 words takes roughly a minute.

The hard part is night thirty, not night one. Give a model the whole history and it slows down and drifts; give it nothing and it forgets the captain's name. So Mirae keeps its own small story bible and hands the model only what tonight needs:

  1. Reference: the genre and premise, plus a short running summary of everything so far.
  2. Cast: who is in the story and their roles, and who has left or died, and when.
  3. Situation: where last night's episode ended.

The genre is a hard rule in the prompt, so a science-fiction story can't wander into fairy tale by night four.

The model proposes, the code decides. Each episode takes two passes through Gemma. The first writes the episode as plain prose. The second reads it back and returns continuity notes as JSON: who joined, who left, who died, a new summary and where things stand. Then deterministic Python applies those notes, not the model:

for removal in update.removed:
    key = removal.name.casefold()
    if key == state.protagonist.casefold():
        notes.append(f"kept {state.protagonist}: the main character stays in the story")
        continue
    leaving = next((c for c in cast if c.name.casefold() == key), None)
    if leaving is None:
        notes.append(f"ignored removal of {removal.name}, who is not in the cast")
        continue
    cast.remove(leaving)
    departed.append(Departure(name=leaving.name, reason=removal.reason, night=night))
Enter fullscreen mode Exit fullscreen mode

Only real cast members can leave, the main character never does, and the dead never come back. If the notes are unusable, the episode is still kept and the cast stays as it was. Episode and story bible are saved in one SQLite transaction, so the story can't fork.

The voice is ElevenLabs. Mirae speaks with ElevenLabs eleven_v4, selected on the robot's Story page, with the API key stored encrypted on the robot. Episodes are streamed paragraph by paragraph, so the first words arrive in about two seconds instead of after the whole chapter is rendered. Piper is built in as an offline voice, one setting away.

Does it hold together? The continuity rules, storage, API and voice are covered by 167 passing tests. In the live run, Gemma 4 wrote two science-fiction nights about Captain John and his engineer Clay, on night two both stayed exactly who they were, and a new character, Kael, was added to the cast automatically.

Why Does Open Innovation Matter?

  • A bedtime story is personal. The characters are often your kids, your partner, your inside jokes. With an open model running locally, the premise, the cast and every episode stay on your own hardware.
  • A story every night shouldn't cost per token. Locally, a year of episodes costs electricity.
  • The memory belongs to the robot, not a vendor. The story bible lives in Mirae, not in someone's chat history, so I can swap Gemma for a smaller or different open model and John and Clay are still John and Clay.
  • I can design for small hardware. The capped summary keeps the context small enough for modest devices; others have shown small Gemma 4 models running on a Raspberry Pi 5 (Deploying Gemma 4 2B on a Raspberry Pi 5). I haven't measured Mirae's storyteller on the Pi yet; today Gemma 4 12B runs on my desktop and the robot talks to it over the home network.
  • Consistency needed control a closed API wouldn't give me. AI characters are known to drift (Why AI characters drift when you switch models). With an open model I own the prompt, the memory and the rules around it, which is exactly where the fix had to go.

The Lazy Payoff

  • Once: about a minute to choose a genre, write a premise and name the characters.
  • Every night: one request. About a minute later Mirae starts reading a two-to-three-minute chapter, then turns itself off.
  • Never again: inventing a plot, remembering the cast, or working out where you stopped.

So far I've run it for a couple of nights, during this challenge week.

Prize Categories

  • Best Use of Gemma: Gemma 4 (12B) via Ollama writes every episode and the continuity notes.
  • Best Use of ElevenLabs: eleven_v4 voices Mirae (story narration and spoken output), plus ElevenLabs Music for the film's score and a second ElevenLabs voice for the listener.

Top comments (0)