Dev.to AI πŸ€– Ai πŸ‘ 0 πŸ“– 7 min read

Said It: Gemma finds the 6 promises I forgot, offline, in 17 seconds

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady What I Built "Kal bhej dunga" is the most broken promise in India, and I've said it in every group chat I'm in. Sai

Said It: Gemma finds the 6 promises I forgot, offline, in 17 seconds

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

What I Built

"Kal bhej dunga" is the most broken promise in India, and I've said it in every group chat I'm in.

Said It reads your exported WhatsApp chat on your own laptop, finds the promises you made, works out which ones are late, and drafts the "sorry, here it is" reply. Gemma runs locally in Ollama, so 0 bytes of your chat leave the machine.

Who gets to be lazier: anyone in a group project, a flat group or a family chat who types "will do tomorrow" and then sleeps for a week.

Task Before With Said It Saved
Find every promise I made Reread all 29 messages 16.9 s, 17 local model calls the reread
Messages I actually read 29 6 cards (3 late, 2 due soon, 1 already kept) 23 fewer (βˆ’79%)
Turn "kal" / "parso" into a date a week later Mental math (or forget) Computed in code: kal = +1 day, parso = +2 No guessing
Write the apology reply sit there wording it Drafted in 0.86 s, 9 words the blank-box stare

By the numbers

  • 3.4 GB: the whole model (gemma3:4b) on disk
  • 16.9 s: a full run of 17 Gemma calls on an RTX 4050 Laptop GPU
  • ~50 tokens/s: average generation speed (range 42–56)
  • 6 / 6: promises found in the sample chat, with 0 decoys flagged
  • 0 bytes: chat text sent anywhere except localhost:11434
  • 3: commands to run it

Demo

Live site: ayushkr23.github.io/said-it. Without Ollama it replays a real recorded run. With Ollama, it runs live on your own machine.

Watch the 1:23 explainer: YouTube

GitHub logo ayushkr23 / said-it

Find the promises you made in WhatsApp, offline, with Gemma.

Said It

Finds the promises you made in a WhatsApp export, on your laptop, with Gemma through Ollama. Chat text is never sent to a remote API.

🎬 Project Demo

SAID-IT Project Demo

▢️ Watch the SAID-IT Demo

Live demo Β· MIT Β· Vite 8 Β· React 19 Β· TypeScript

https://github.com/ayushkr23/said-it/blob/main/docs/said-it.mp4

The 1:23 demo: the chat, Gemma finding the promises, and the one reply. Sound on.

What it does

Export a WhatsApp chat (.txt, or the .zip WhatsApp writes). Drop it in. Said It:

  1. Parses the export in the browser
  2. Reads only your messages
  3. Asks gemma3:4b to quote the commitment words
  4. Turns kal / parso / weekday names into dates in code
  5. Asks a yes/no β€œalready kept?” question per candidate
  6. Drafts one reply, under 25 words

On the bundled sample chat (src/data/sample-chat.txt + src/data/recorded.json):














Before With Said It
Messages you read 29 6 cards (3 late, 2 due
…





Try this in 60 seconds:

  1. On the home page, pull the lever. Everyone else's messages drop away and only your promises are left, stamped.
  2. Flip the Open switch to see what changes when the model lives on your laptop.
  3. Open Run it and press Replay a recorded run: all 17 calls stream in with real timings, no install needed.
  4. Have Ollama? Drop the bundled sample chat (or your own .txt/.zip export) and watch Gemma work live.

Home: You said you'd do it. We noticed.

Lever pulled: only your promises, plus the drafted reply

Verdict: 3 late, 2 due soon, one copyable reply

Code

GitHub logo ayushkr23 / said-it

Find the promises you made in WhatsApp, offline, with Gemma.

Said It

Finds the promises you made in a WhatsApp export, on your laptop, with Gemma through Ollama. Chat text is never sent to a remote API.

🎬 Project Demo

SAID-IT Project Demo

▢️ Watch the SAID-IT Demo

Live demo Β· MIT Β· Vite 8 Β· React 19 Β· TypeScript

https://github.com/ayushkr23/said-it/blob/main/docs/said-it.mp4

The 1:23 demo: the chat, Gemma finding the promises, and the one reply. Sound on.

What it does

Export a WhatsApp chat (.txt, or the .zip WhatsApp writes). Drop it in. Said It:

  1. Parses the export in the browser
  2. Reads only your messages
  3. Asks gemma3:4b to quote the commitment words
  4. Turns kal / parso / weekday names into dates in code
  5. Asks a yes/no β€œalready kept?” question per candidate
  6. Drafts one reply, under 25 words

On the bundled sample chat (src/data/sample-chat.txt + src/data/recorded.json):














Before With Said It
Messages you read 29 6 cards (3 late, 2 due
…







said-it/
β”œβ”€β”€ src/lib/whatsapp.ts     # parses WhatsApp exports (.txt / .zip)
β”œβ”€β”€ src/lib/promises.ts     # filter β†’ classify β†’ dates β†’ kept? β†’ reply
β”œβ”€β”€ src/lib/ollama.ts       # one fetch to localhost:11434, JSON-schema output
β”œβ”€β”€ src/sections/           # lever, night timeline, details, open switch
β”œβ”€β”€ src/pages/Run.tsx       # drop your export, run live or replay
└── scripts/check-parse.ts  # end-to-end run on the sample chat

Quick start: 3 commands (with Node and Ollama installed):

ollama pull gemma3:4b
git clone https://github.com/ayushkr23/said-it && cd said-it && npm i
npm run dev

License: MIT Β· TypeScript Β· React 19 Β· Vite 8 Β· motion Β· fflate Β· Tests: 0 unit tests, 1 end-to-end check script

How I Built It

A small model can't be trusted with judgement, so I gave it only the jobs it can do and checked everything else in code.

 WhatsApp export (.txt / .zip, unzipped in the browser)
            β”‚
            β–Ό
   parse β†’ keep only MY messages (β‰₯3 words, recent)
            β”‚
            β–Ό
 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€ Gemma 3 4B via Ollama (localhost:11434) ────────┐
 β”‚ 1. classify each message β†’ must QUOTE the promise words β”‚
 β”‚ 2. "already kept?" yes/no per candidate                 β”‚
 β”‚ 3. draft one reply ≀ 25 words                           β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚            β–²
            β–Ό            β”‚ code checks: quote exists? done-marker?
   due dates computed in code β†’ late / soon / kept β†’ UI

Why gemma3:4b: it's 3.4 GB, runs at ~50 tok/s on a laptop GPU, and handled Hinglish lines like "parso tak viva questions ka doc share karta hu" in my sample with no translation step.

The pipeline (runs on demand, once per export):

  1. Parse and filter in the browser: 29 messages become 9 of mine worth reading.
  2. Classify, one message per call: 9 calls, ~1.38 s each. The output is forced into a JSON schema.
  3. Date in code: "kal" = +1 day, "parso" = +2. A promise with no date goes stale after 2 days.
  4. "Already kept?" check: 7 calls, ~0.51 s each, comparing each promise with later messages.
  5. Reply for the easiest late promise: 1 call, 0.86 s, under 25 words, retried if the rules fail.

Design decisions:

  • One message per call, so a single confusing line can't throw off the whole batch.
  • The model never does date maths. Code does.
  • Temperature is 0.1 and the output is JSON only, so runs repeat closely.

What was hard:

  • Gemma said "yes, promise" to almost everything. The fix: the schema makes it quote the exact commitment words before deciding, and code rejects the result if that quote isn't really in the message.
  • "Sent the SQL dump" looked like a promise. Past-tense completion words ("sent", "booked", "done", plus Hindi equivalents) are now filtered out before Gemma ever sees the message.
  • Saying a promise was kept was too easy. I narrowed it to one yes/no question per candidate, against messages that came after it.

Tradeoffs and limitations:

  • Accuracy is measured on one sample chat I wrote myself (6 promises, 3 decoys). That's a smoke test, not a benchmark.
  • The parser targets Android export format. The UI accepts a .zip (how iPhone exports often arrive); treat iOS as unverified.
  • Fonts load from Google Fonts. No chat data goes with that request. "Works with wifi off" is not verified.
  • The hosted site needs OLLAMA_ORIGINS set before it can talk to your local Ollama. Until then, replay still works.

Why Does Open Innovation Matter?

A group chat is the most private text you own, and it's full of friends who never agreed to have it uploaded.

Closed API Open-weight Gemma (Said It)
Chat text sent out Every message you analyse 0 bytes
Cost per run (~5,900 tokens) Per-token billing β‚Ή0 marginal
Needs internet Yes No, except Google Fonts on first load
Model changes under you Whenever the provider updates it Pinned: gemma3:4b
Can you inspect it? Prompts only Prompts, schema, weights

Said It only works because the model sits next to the data. A pinned open model means my 6/6 result is the same next month; a silently updated closed model could break the quote check overnight.

Fork it, point Ollama at a different open model, and you have a promise tracker for Telegram, Slack or your own language.

The Lazy Payoff

Every run costs 16.9 seconds and β‚Ή0. The time it saves is the reread you no longer do.

On the sample: 29 messages down to 6 cards, one 9-word reply, 23 messages you don't have to look at again. That's the sloth version of a weekly review.

I haven't timed a stranger using it yet. If you run it on a real chat, tell me how many late cards it printed.

The sloth didn't get faster. It just stopped forgetting.

Prize Categories

Best Use of Gemma: all 17 model calls, from finding promises to the "already kept?" check to the drafted reply, are gemma3:4b running locally in Ollama, for 16.9 s per run.

Best Use of ElevenLabs: the 1:23 explainer is narrated with ElevenLabs. I wrote the script, generated the voice there, and synced it to the film: the chat, Gemma finding the six promises, and the one reply. Watch it on YouTube. The app stays local. ElevenLabs is the voice of the demo, not a call the app makes.

Try it in 3 commands, and tell me what you promised and forgot.
Star the repo if Said It caught you too.

πŸ“° Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.