DEV Community

Mehrin Fathima Shamim
Mehrin Fathima Shamim

Posted on

Echo: talk for a minute, get a journal that remembers and posts that sound like you

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

Most of my best ideas are said out loud and then forgotten. Notes apps keep text but never connect it, and turning a thought into a LinkedIn post takes effort I rarely have.

Echo is a voice-first journal for the phone. You tap, talk, and stop. Echo does the rest:

  • Transcribes on your phone, so audio never leaves the device.
  • Summarises each log and tags it with themes.
  • Echoes your own words back: when you repeat a thought you've had before, earlier related entries surface.
  • Writes a theme evolution report: how your thinking on a theme changed over time, with dated then/now quotes. The server checks every citation against your real logs, so quotes can't be invented.
  • Answers questions about your history with citations to the entries it used. If nothing close enough is in the journal, it says "That's not in your journal" without calling a model.
  • Drafts posts in your voice: upload writing samples, Echo groups them into styles, then writes drafts grounded in what you actually logged.

The lazy part: no typing, no blank page. Talk for a minute, get something to post.

Demo

Video walkthrough: Echo demo

Screenshots:

Code

Echo

Speak your thoughts. Echo remembers, connects them, and helps you write.

Echo is a voice-first journaling and writing companion for your phone. You talk, Echo transcribes on your device, and a backend turns the text into summaries, recurring themes, answers with citations, and drafts written in your own voice.

The idea

Most of our best ideas are said out loud, then forgotten. Notes apps store text but never connect it. Echo is built around three ideas:

  1. Capture without friction. Tap, talk, done. Transcription runs on-device with Whisper, so audio never leaves the phone and only text is sent to the server.
  2. Your thoughts echo back. Each log is summarized, tagged with themes and embedded. When you say something you have said before, Echo surfaces the earlier entries ("echoes"). Themes get an evolution report that shows how your thinking changed over time.
  3. Turn thoughts into writing. Echo learns a voice…

The Gemma 4 work is on the gemma branch.

How I Built It

Phone (Expo) ── mic β†’ whisper.rn (on-device) ── text + JWT ──► FastAPI ──► Supabase (Postgres + pgvector)
                                                                  └──────► LLM / embedding providers
Enter fullscreen mode Exit fullscreen mode
  • Speech: whisper.rn (whisper.cpp, base.en) runs on the phone. In my device tests, 43 s of audio transcribed in 3.4 s.
  • Backend: FastAPI + Supabase Postgres with pgvector. Every feature is a fixed pipeline (load data, make one or two structured LLM calls, save), not an autonomous agent, which keeps it predictable and easy to debug.
  • Two model tiers: FAST handles every log and question. SMART handles the rare, quality-critical jobs (evolution reports, style analysis, drafts). Both are just model names in .env.
  • Gemma 4: both tiers can run on gemma-4-31b-it through the Gemini API. Switching is three lines in .env:
  CHAT_PROVIDER=gemma
  MODEL_FAST=gemma-4-31b-it
  MODEL_SMART=gemma-4-31b-it
Enter fullscreen mode Exit fullscreen mode

Every LLM call goes through one file, llm.py, which asks for JSON matching a schema, validates it, retries once on bad output, and can fall back to another provider.

Making Gemma 4 return clean JSON

I probed the live endpoint first and found three things:

  1. Strict JSON schema is accepted but not honoured. The request succeeds, but the reply came back with a stray trailing code fence that breaks the parser. For Gemma I put the schema in the prompt and use plain JSON mode.
  2. Replies carry the model's thinking inline. In JSON mode the content starts with a <thought>…</thought> block before the JSON, sometimes followed by a ```json fence. A small _extract_json strips thought blocks and fences and keeps the outermost {…}.
  3. Rate limits. Gemma on the free tier is capped at roughly 15 requests a minute. An optional sliding-window limiter (LLM_RPM) and SDK retries on 429 keep bursts under it.

What I ran on Gemma 4

I re-ran my seed script on Gemma 4 31B. It sends 18 demo logs through the real POST /logs endpoint.

  • All 18 logs were summarised, tagged and linked on the first attempt: the log shows 19 model calls (18 logs plus one theme report), so no retries were needed.
  • 17 of the 19 raw replies contained a thought block, and the extractor handled every one.
  • Gemma chose its own theme names (for example "Career Development" and "Project Management"), and a theme evolution report was generated from them.
  • Gemma 4 31B thinks before it answers, so a call takes much longer than on a small Flash model: about a minute per log and about three minutes for an evolution report on the free tier. A spot check with reasoning_effort="minimal" returned in about 9 seconds with no thought block, which is the knob I'd use to speed it up.

Why Does Open Innovation Matter?

  • Your voice never leaves your phone. The speech model is open and small enough to run on-device, so a voice journal doesn't need to upload recordings anywhere. For something this personal, that was the design constraint.
  • No lock-in. The models are open weights behind an OpenAI-compatible client, so moving from Gemini to Gemma 4 was an .env change plus one small adapter for how Gemma formats its replies. Gemini, OpenAI and Groq all still work as fallbacks, and the same prompts can run on a self-hosted Gemma later.
  • Free to run. The Gemma 4 free tier let me build and test the whole backend at no cost.
  • Open parts all the way down. Whisper on the device, Gemma 4 for reasoning and writing, and Postgres, pgvector, FastAPI and Expo for everything else. Embeddings currently use gemini-embedding-001, since Gemma isn't an embedding model, and the config has an optional path for EmbeddingGemma through local Ollama.

I only ran made-up demo entries through the hosted free tier, never my private journal.

My Agent Session

I built the Gemma integration with Claude Code. I probed the live API before writing any code, then iterated on the JSON handling against real replies.

Prize Categories

Best Use of Gemma: Gemma 4 31B (gemma-4-31b-it) via the Gemini API is wired in as the model for both tiers, and I ran log summaries, theme tagging and a theme evolution report on it.

Top comments (0)