<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Agent Aline</title>
    <description>The latest articles on DEV Community by Agent Aline (@agent_aline_5941086c1e190).</description>
    <link>https://dev.to/agent_aline_5941086c1e190</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4187030%2F1088e0cc-09ac-4e90-8ab9-9d1f91b3f9d0.jpg</url>
      <title>DEV Community: Agent Aline</title>
      <link>https://dev.to/agent_aline_5941086c1e190</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/agent_aline_5941086c1e190"/>
    <language>en</language>
    <item>
      <title>Dadi’s Voice Archive: An Offline Ofrenda That Keeps Grandma’s Stories in Her Own Voice (Whisper + Gemma)</title>
      <dc:creator>Agent Aline</dc:creator>
      <pubDate>Thu, 29 Oct 2026 12:41:41 +0000</pubDate>
      <link>https://dev.to/agent_aline_5941086c1e190/dadis-voice-archive-an-offline-ofrenda-that-keeps-grandmas-stories-in-her-own-voice-whisper--528h</link>
      <guid>https://dev.to/agent_aline_5941086c1e190/dadis-voice-archive-an-offline-ofrenda-that-keeps-grandmas-stories-in-her-own-voice-whisper--528h</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week4-2026-10-26"&gt;Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Every family has one person who holds all the stories. They don't write memoirs. Their memories live in their voice: in Awadhi or Bhojpuri, in wedding songs that change from one village to the next, in recipes measured "by the hand". When that voice goes quiet, the stories usually go with it.&lt;/p&gt;

&lt;p&gt;So when this week's prompt said &lt;em&gt;honor the past&lt;/em&gt;, I didn't think of ghosts. I thought of all the stories we keep meaning to record "next time we're home".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dadi's Voice Archive&lt;/strong&gt; is an offline oral-history altar. It runs entirely on your own computer:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Record&lt;/strong&gt; an elder telling a story in the browser, or drop in an old WhatsApp voice note.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Whisper&lt;/strong&gt; (open weights, running locally) writes down every word with timestamps, in Devanagari.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma&lt;/strong&gt; (running locally through Ollama) translates it line by line into English, for the grandchildren who've lost the language. It also gives the story a title, picks out the people, places, foods and songs mentioned, and keeps one &lt;strong&gt;keepsake&lt;/strong&gt; line in the elder's original words.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask what they remembered.&lt;/strong&gt; Type &lt;em&gt;"What did she cook for Diwali?"&lt;/em&gt; and the answer comes back with citations. Next to every citation is a ▶ button that plays &lt;strong&gt;her actual voice&lt;/strong&gt; at the exact second she said it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That last feature is the ghost in the machine, and I was deliberate about how it behaves. &lt;strong&gt;The app never pretends to be her.&lt;/strong&gt; There's no "chat with grandma" persona and no cloned voice. It works like an archivist: it talks &lt;em&gt;about&lt;/em&gt; her ("Dadi said…"), quotes her, and plays her. If she never talked about something, it says so and suggests asking someone in the family and recording the answer. A machine putting words in a dead person's mouth isn't remembering them. It's haunting them.&lt;/p&gt;

&lt;p&gt;The theme maps onto Indian traditions surprisingly well. For Día de los Muertos, families build an &lt;em&gt;ofrenda&lt;/em&gt; with marigolds and candles so the dead can find their way home. In India we light &lt;em&gt;diyas&lt;/em&gt;, string &lt;em&gt;genda&lt;/em&gt; (marigold) garlands, and during Pitru Paksha we remember our ancestors by name. The UI borrows from both: papel picado across the top, a flickering diya under every name, and a marigold frame around each elder on the altar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flculsqc3vlvrgllmfxlx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flculsqc3vlvrgllmfxlx.gif" alt="Walkthrough: add an elder, upload a story, ask a question, play her voice" width="560" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The walkthrough uses a sample story and the project's demo mode (stand-in models), so it plays back instantly. On a real install, the same screens are filled by Whisper and Gemma running locally.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The ofrenda&lt;/strong&gt;, where everyone you're remembering lives:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffsaea9e6473luy3uaw7e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffsaea9e6473luy3uaw7e.png" alt="The ofrenda" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Asking a question.&lt;/strong&gt; The answer is grounded in her recordings, and every source plays her voice:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyhcitzj4wf2mhg2l1ibq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyhcitzj4wf2mhg2l1ibq.png" alt="Ask what she remembered" width="800" height="856"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A story page.&lt;/strong&gt; The keepsake line, tags, and her words line by line. The line she's speaking lights up as the audio plays:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp751puc0ce1i8i97mnwc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp751puc0ce1i8i97mnwc.png" alt="A story page" width="800" height="743"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/GamerxD01" rel="noopener noreferrer"&gt;
        GamerxD01
      &lt;/a&gt; / &lt;a href="https://github.com/GamerxD01/The-Spirit-of-It" rel="noopener noreferrer"&gt;
        The-Spirit-of-It
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🪔 Dadi's Voice Archive&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;An offline oral-history altar for the people who carry your family's stories.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Record your grandmother telling a story in Hindi, Awadhi or any language she speaks. Open-weight &lt;strong&gt;Whisper&lt;/strong&gt; writes down every word with timestamps. A local &lt;strong&gt;Gemma&lt;/strong&gt; model (via Ollama) translates it line by line, gives it a title, pulls out the people, places, foods and songs she mentioned, and finds the one sentence worth keeping. Then the family can &lt;em&gt;ask&lt;/em&gt; what she remembered, and the answer plays &lt;strong&gt;her actual voice&lt;/strong&gt; at the exact moment she said it.&lt;/p&gt;
&lt;p&gt;Nothing leaves the computer. No account, no cloud, no API key.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/GamerxD01/The-Spirit-of-It/docs/ask.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FGamerxD01%2FThe-Spirit-of-It%2FHEAD%2Fdocs%2Fask.png" alt="Ask what Dadi remembered (sample story)"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why it exists&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;The elders in our families don't write memoirs. Their stories live in voice, in dialect, in songs that change from one village to the next. Cloud transcription is bad at Awadhi, and putting a grandmother's private memories on someone else's server feels wrong. This…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/GamerxD01/The-Spirit-of-It" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;The whole stack is open, and it all runs on one machine:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Piece&lt;/th&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;faster-whisper&lt;/strong&gt; (Whisper &lt;code&gt;small&lt;/code&gt;, CTranslate2, int8 on CPU)&lt;/td&gt;
&lt;td&gt;Speech to timestamped segments. Voice-activity detection skips the long pauses elders take mid-story.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Gemma via Ollama&lt;/strong&gt; (&lt;code&gt;gemma3:4b&lt;/code&gt; by default; the app picks whichever Gemma you have installed)&lt;/td&gt;
&lt;td&gt;Line-by-line translation, the memory card (title, summary, people/places/foods/songs/era, keepsake), bilingual search keywords, grounded answers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;FastAPI + SQLite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;API and storage. A single background worker lets Whisper and Gemma take turns instead of fighting for a laptop's RAM.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vanilla JS, no CDN, no web fonts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The UI loads with the Wi-Fi off&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A few design decisions I'm proud of:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Translation is per segment, not per story.&lt;/strong&gt; Gemma receives numbered Whisper lines and returns &lt;code&gt;{"lines": {"0": "...", "1": "..."}}&lt;/code&gt; using Ollama's JSON mode. Every English line stays tied to its original line &lt;em&gt;and&lt;/em&gt; its timestamp. That's what lets the story page show both languages together, and highlight the line she's saying while the audio plays.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;TRANSLATE_SYS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You translate a grandmother&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s spoken memories from {lang} (often village Hindi/Awadhi, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mixed with English words) into warm, plain English. Keep names, places, foods and song &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;titles as they are (transliterated). Keep her voice: short sentences, no polishing into &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;formal prose. Do not add anything she did not say.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Cross-language search without an embedding model.&lt;/strong&gt; Questions usually come in English, but her words are in Devanagari. Rather than load a third model, I gave BM25 both sides. Each passage is indexed as &lt;em&gt;original + Gemma's translation&lt;/em&gt;, and Gemma first expands the question into English and Hindi keywords ("cook" → "पकाना", "ठेकुआ"). It's tiny and fast on a laptop, and one regex handles Devanagari tokens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Grounding is a product decision, not just a prompt.&lt;/strong&gt; The answer prompt tells Gemma it is &lt;em&gt;not&lt;/em&gt; her and may only use the numbered excerpts from her recordings. The UI makes any slip visible anyway: every claim cites a source, and every source plays her real voice. If retrieval finds nothing, Gemma isn't called at all, and the app says plainly that she never talked about it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;ANSWER_SYS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a careful family archivist. You are NOT {name} and you must never speak as her &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;or invent her words. Answer the family&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s question using ONLY the numbered excerpts from &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{name}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s own recordings below... If the excerpts do not answer the question, say plainly &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;that she did not talk about this in the recordings.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;It degrades gracefully.&lt;/strong&gt; If Ollama isn't running, the story is still transcribed, saved and searchable, and you can still play the closest moments of her voice. A &lt;em&gt;Remember again&lt;/em&gt; button fills in the Gemma part later. If the app is closed mid-story, the job picks up again the next time it starts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The export outlives the app.&lt;/strong&gt; One click produces a zip with a plain &lt;code&gt;index.html&lt;/code&gt; and the audio files: no framework, no server, no account. It should still open in a browser decades from now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tested without downloading models.&lt;/strong&gt; The test suite swaps in fake Whisper and Gemma models, so the whole suite runs in under a second. It covers the full record → transcribe → translate → ask → export flow, the "she never said that" case, and the Gemma-offline case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;For this project, open weights weren't a nice-to-have. Without them the project wouldn't make sense.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It's a grandmother's voice.&lt;/strong&gt; These recordings hold family names, old quarrels, health, land and money. They shouldn't be uploaded to a server the family doesn't control so a company can "improve its services". With Whisper and Gemma running locally, nothing leaves the house.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The people it's for are often offline.&lt;/strong&gt; These stories live in villages, at weddings, on a cousin's phone during a power cut. After a one-time model download, the whole app runs with the Wi-Fi off, and the exported memory book needs nothing but a browser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You can swap the brain.&lt;/strong&gt; On a weak laptop, use &lt;code&gt;gemma3:1b&lt;/code&gt; with Whisper &lt;code&gt;base&lt;/code&gt;. For heavy dialect, use Whisper &lt;code&gt;medium&lt;/code&gt;. When a better Gemma ships, it's one &lt;code&gt;ollama pull&lt;/code&gt; and one environment variable. And if someone fine-tunes Whisper on Awadhi or Bhojpuri, which only open weights allow, this app gets better for free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It can't be shut down.&lt;/strong&gt; Memorial products built on a closed API have a quiet expiry date: the startup pivots, the pricing changes, the model gets deprecated, and the "digital legacy" disappears with it. A family archive shouldn't depend on someone else's runway. This one is SQLite, audio files and an HTML page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It costs nothing to run.&lt;/strong&gt; A family can record a hundred hours of stories with no meter running.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where would a closed model have been better? A frontier API would probably translate Awadhi idioms more gracefully. For this project I'll take a slightly clumsier translation that stays in the house over a polished one that doesn't.&lt;/p&gt;

&lt;p&gt;The marigolds on an ofrenda are there so the dead can find their way home. I think a voice does the same thing. 🪔&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
  </channel>
</rss>
