A local-first AI pet that lives on your desktop.
Mochi moves on her own, remembers what matters, and chats briefly through an optional local LLM. Fully offline. No accounts. No cloud. No telemetry.
This is the real simulation — every 3 s tick runs the same pure decay, mood and movement rules the desktop app runs. How it works ↓
- Alive without the LLM.A deterministic local simulation drives mood, needs, movement and sleep — every 3 seconds, all day, no network calls.
- The LLM only speaks at salience moments.Short greetings and reflections, behind a salience gate and hard cooldowns. No spam, no surprise bills.
- Memory you can read and delete.SQLite + FTS5, ranked by importance × recency × confidence. Export to Markdown anytime.
- Sandbox by default.She reads only what you drop into her inbox, only after explicit per-file consent — never your filesystem at large.
Clone it and meet her
No installers yet — the honest path is clone-and-run. She’s happy in silent mode; the chat is optional.
$ git clone https://github.com/cskwork/pet-mochi.git $ cd pet-mochi $ npm install $ npm run tauri:dev # launches the desktop pet
Requirements: Node ≥ 20, Rust ≥ 1.77, Windows / macOS / Linux. Optional: Ollama with a small model for chat replies — ollama pull gemma4:e2b, then Settings → provider ollama.
Under the hood
Cute surface, rigorous underneath. The pet is a simulation first — the LLM is seasoning, not the meal.
| Layer | Tech | Role |
|---|---|---|
| Desktop shell | Tauri 2 | Transparent, always-on-top, draggable overlay. |
| UI | Svelte 5 + TypeScript | PNG sprite + CSS animation, no extra renderer. |
| Simulation engine | TypeScript pure functions | Mood, decay, movement — testable, no LLM required. |
| Memory engine | Rust + rusqlite + FTS5 | Durable memories, prefix search, weighted ranking. |
| LLM adapter | Rust + reqwest | Pluggable LlmProvider trait; Ollama is the first implementation. |
| Sandbox | Rust | Inbox watcher, path-jail safe IO, declarative skills. |
Six moods you can read at a glance
Hidden stats decay every tick; the first matching rule wins. A color tint plus a distinguishing glyph keeps similar tones apart — watch them drift live in the device above.
She finds a quiet corner and sleeps it off.
The 🍡 glyph appears; the snack tray starts looking interesting.
Wanders off to explore — the “…” glyph gives it away.
A ♡ asks for a pat. She never guilt-trips, only hopes.
A “?” floats up when something novel is nearby.
The default. Idle quirks, wiggles, and the occasional celebrate.
Every pose is hand-drawn
28 sprites, one character, each with its own CSS motion in the app — plus per-mood color tints layered on top. These are the real files, straight from public/sprites/.
Optional: give her a voice
Mochi is silent by default and fine with it. With a local Ollama model she adds short, mood-aware, in-character replies — and the leash stays short.
$ ollama pull gemma4:e2b # then: Settings → provider: ollama # endpoint: http://localhost:11434
- Salience-gated, cooldown-capped.An event must clear salience
≥ 70and wait out a90 sautonomous cooldown. No care action alone reaches the gate — Play is 40, Feed 35, Rest 25, Pat 20. - Memory before words.Relevant memories are retrieved and re-ranked by 0.4·importance + 0.3·recency + 0.3·confidence, so old-but-important beats fresh trivia.
- Failure is graceful.Ollama offline, DB unavailable, garbled extraction — the pet keeps animating. Failures log warnings, never bubble up.
Her whole world is one folder
A path-jailed sandbox (canonicalized, verified, no .., no absolute escapes, no symlinks that resolve outside). Want her somewhere else? Point MOCHI_HOME at it.
pet-mochi/ ├─ inbox/ ← drop .txt / .md / .json here ├─ notes/ ← she writes summaries ├─ dreams/ ← daily reflections ├─ exports/ ← memory exports └─ mochi.db # SQLite memory + state
- Reads only from
inbox/, and only after explicit per-file consent. - Writes only to
notes/,dreams/,exports/. - No shell, no
eval, no remote skill loading — ever. - Every path is canonicalized and jailed before any read or write.
Coming next — clearly not shipped yet
- Voice (opt-in)
- Custom skins
- Live2D / VRM
- Git & test-runner watcher
- Local embedding memory search
- Multiple pets
- Wardrobe & growth stages
“The pet must feel alive even when the LLM is off.”— Project North Star, PRD §1