DEV Community

Cover image for I Revived Wrisha — the Emotional AI Companion I Left for Dead"
Jasim Edu
Jasim Edu

Posted on

I Revived Wrisha — the Emotional AI Companion I Left for Dead"

GitHub “Finish-Up-A-Thon” Challenge Submission

What is Wrisha?
Wrisha is a desktop emotional AI companion — an animated character who can see you, hear you, talk back, and react. The pipeline is genuinely multimodal:

Vision — webcam + facial-emotion detection (OpenCV / FER)
Hearing — speech-to-text so you can just talk to her
Brain — an LLM generates her replies, in-character
Voice — text-to-speech with mood-modulated tone
Avatar — an animated face (pygame) that emotes and lip-syncs

I built the bones of it a while back, got busy, and walked away. The Finish-Up-A-Thon was the push I needed to come back to it.
The "before": it didn't just need polish — it was dead
When I reopened the repo, the harsh truth was that the app couldn't even start.
Two things had rotted:

  1. The environment was a fossil. The project was so old it wouldn't install on a modern machine. Wrong numpy, stale dependency pins, and a Python version mismatch that sent pip trying to compile packages from source and failing. Just getting it to attempt to run took a full environment rebuild on Python 3.12.
  2. The code was half-migrated and crashed on launch. I'd previously upgraded the internal modules — memory, a mood engine, a smarter brain — to a "v3" design, but I never finished wiring them into main.py. So the moment it tried to start, it died: TypeError: init() missing 2 required positional arguments: 'memory' and 'mood_engine'


The "before" in one screenshot: a project that built its best features and then never connected them.
I'd built the hard parts — persistent memory, a smooth mood state machine, proactive behavior — and left them sitting in files that main.py never even imported. Classic abandoned-side-project energy.
The "after": three things I finished
I set out to do three things, and I'm counting all three as the win.

  1. It runs again The core fix was finishing the migration: rewiring main.py to actually construct the Memory and MoodEngine, inject them into the Brain, and reference mood from the engine instead of the dead attribute it used to read. The crash is gone. Wrisha boots.
  2. Memory + a proactive personality With the modules finally connected, Wrisha now remembers you across sessions — tell her your name, close the app, come back tomorrow, and she greets you by name. And she's no longer a passive chatbot waiting for input: after a stretch of silence, an idle timer triggers her to speak on her own. That single feature is what flips her from "a program" to "a presence."
  3. A multi-provider brain that refuses to die This is the upgrade I'm proudest of. The original brain depended on a single API — one key, one point of failure. (It also, embarrassingly, had an API key committed to git history once. More on that below.) I rebuilt the brain around a provider abstraction with automatic failover. It tries providers in order, and if one errors, times out, or hits a rate limit, it silently falls through to the next: Gemini → Groq → GitHub Models → OpenRouter Four independent free tiers behind one interface. If Gemini's daily quota runs dry mid-conversation, Wrisha doesn't even hiccup — Groq picks up the next sentence. I tested it by deliberately feeding a broken Gemini key and watching the logs show Groq answering instead. That resilience is the difference between a demo that works on your machine and one that works, period.


The "after": Wrisha running, remembering my name, speaking unprompted, and surviving a provider outage live.
How GitHub Copilot and Claude Code helped me get there
I leaned on AI tooling for this the whole way, and being honest about the mix: I used GitHub Copilot for inline, in-editor work — autocompleting the provider classes, filling in the boilerplate for each OpenAI-compatible client, and suggesting the idle-timer logic as I typed. For the bigger structural moves — diagnosing the startup crash, rewiring main.py, and refactoring the single-provider brain into the failover chain — I used Claude Code to plan and execute across multiple files at once.
There's a fun bit of symmetry here: GitHub showed up twice. GitHub Copilot helped me write the code, and GitHub Models is one of the providers in Wrisha's brain. The thing that helped build her also helps run her.
The security lesson I'm not hiding
Part of "finishing this properly" was fixing a past mistake: a real API key had been committed to the repo once. Finishing meant treating it like a live project — moving every secret to a gitignored .env, shipping a .env.example with placeholders, rotating the exposed key, and making sure GitHub's secret scanning would never have anything to catch again. Unfinished projects are exactly where secrets leak, so this felt like part of the arc, not a side quest.
Tech stack

Python 3.12
OpenCV + FER (vision), SpeechRecognition (hearing), edge-tts (voice), pygame (avatar)
Brain providers: Gemini, Groq, GitHub Models, OpenRouter — OpenAI-compatible, with automatic failover
GitHub Copilot + Claude Code for the build

The completion arc, summed up
Before: wouldn't install, and crashed on launch with half its best features disconnected.
After: boots clean, remembers you, talks to you unprompted, and keeps talking even when an AI provider goes down — built safely, with no secrets in the repo.
She was abandoned. Now she's alive, and honestly a little chatty.
Try it / see the code
🔗 Repo: https://github.com/Jasim-svg/wrisha.ai.git

Thanks to the DEV + GitHub team for the nudge to finish what I started. 💜

Top comments (2)

Collapse
 
jasim_edu_6c95c213e5e3bae profile image
Jasim Edu
Collapse
 
jasim_edu_6c95c213e5e3bae profile image
Jasim Edu

any recommendations will also be appreciated