<?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: RAKOTONDRAINIBE Rohiniaina Maria Grazia</title>
    <description>The latest articles on DEV Community by RAKOTONDRAINIBE Rohiniaina Maria Grazia (@lonewolfnyx).</description>
    <link>https://dev.to/lonewolfnyx</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%2F4154440%2F78c25fa9-de85-490b-b0b1-98427416407f.jpg</url>
      <title>DEV Community: RAKOTONDRAINIBE Rohiniaina Maria Grazia</title>
      <link>https://dev.to/lonewolfnyx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lonewolfnyx"/>
    <language>en</language>
    <item>
      <title>Nook</title>
      <dc:creator>RAKOTONDRAINIBE Rohiniaina Maria Grazia</dc:creator>
      <pubDate>Mon, 12 Oct 2026 06:58:45 +0000</pubDate>
      <link>https://dev.to/lonewolfnyx/nook-53be</link>
      <guid>https://dev.to/lonewolfnyx/nook-53be</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05"&gt;Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Nook: I Built an AI Field Guide That Sends You Back Outside
&lt;/h1&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%2Fcr437gcogjxeqra23ft5.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%2Fcr437gcogjxeqra23ft5.png" alt=" " width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Nook is a nature fieldwork companion that turns your phone into a naturalist's notebook, and then invites you to keep exploring your environment.&lt;/p&gt;

&lt;p&gt;You snap a photo of something you found outside: a leaf between two colors, a bark carved by insects, an odd shadow, a pebble that looks like it's been through something. Gemma 4, running as the core of the backend, looks at it with a field naturalist's eye.&lt;/p&gt;

&lt;p&gt;The app is for anyone who's walked past interesting things a thousand times and never stopped to actually look. Kids, curious adults, people who want to spend more time outside but don't know where to start.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://nook-i5bl.onrender.com" rel="noopener noreferrer"&gt;https://nook-i5bl.onrender.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I recorded the demo with my phone to be able to take photos. And also, because it's the main use finality of this project:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://drive.google.com/file/d/1l_eKY_cCYliWyQT_D7-aZC9QfOgWQHhx/view?usp=drive_link" rel="noopener noreferrer"&gt;Demo video&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Welcome tab&lt;/strong&gt;: the landing screen &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;on a smartphone:
&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%2Fiun7la15trttigrbj692.jpg" alt="Welcome tab" width="720" height="1612"&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Discovery tab&lt;/strong&gt;: The result of gemma's analysis&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;on a smartphone:&lt;br&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%2F0uu0yvkanqbkylmaote8.jpg" 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%2F0uu0yvkanqbkylmaote8.jpg" alt="Discovery tab" width="720" height="1612"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;on a computer:&lt;br&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%2Fhujdih2nd2s2h3hoi0qy.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%2Fhujdih2nd2s2h3hoi0qy.png" alt="Discovery tab" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Poster tab&lt;/strong&gt;: The journal of all of your discoveries&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;on a smartphone:&lt;br&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%2Fmckw5mi1g2chjvpaaom6.jpg" 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%2Fmckw5mi1g2chjvpaaom6.jpg" alt="Poster tab" width="720" height="1612"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;on a computer:&lt;br&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%2Fjorw0r1gyyhj7d126i1v.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%2Fjorw0r1gyyhj7d126i1v.png" alt=" " width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full flow in three steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Observe&lt;/strong&gt; — snap or upload a photo from your phone (mobile-first, works with &lt;code&gt;capture="environment"&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Investigate&lt;/strong&gt; — Gemma 4 returns a structured Field Card:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What it sees (actual, specific observations from your photo — not generic filler)&lt;/li&gt;
&lt;li&gt;Possible identification + alternatives&lt;/li&gt;
&lt;li&gt;Two hypotheses on why it looks the way it does&lt;/li&gt;
&lt;li&gt;What the photo can't tell (honestly stated)&lt;/li&gt;
&lt;li&gt;An investigation question to sharpen your attention&lt;/li&gt;
&lt;li&gt;A safe outdoor mission to go do immediately&lt;/li&gt;
&lt;li&gt;An Atelier — a concrete creative task you can make from what you found (a leaf rubbing, a bark sketch, a pine cone decoration, a pressed flower)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Investigate + Preserve&lt;/strong&gt; — talk to the ElevenLabs voice agent when you return, then save the session to your local field journal&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github/RoxyMaxy/Nook" rel="noopener noreferrer"&gt;https://github/RoxyMaxy/Nook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stack: Flask · Vanilla JS · Gemma 4 via Google AI Studio · ElevenLabs TTS + Agent · Render · Service Worker PWA&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;The AI layer&lt;/strong&gt; is two services. &lt;code&gt;ai_service.py&lt;/code&gt; sends the image to &lt;code&gt;gemma-4-31b-it&lt;/code&gt; via the &lt;code&gt;google-genai&lt;/code&gt; SDK with a strict JSON schema prompt — the model has to return eight structured fields, each capped at 25 words, in a concrete naturalist tone. No markdown, no filler, just what it actually sees. &lt;code&gt;parser_helper.py&lt;/code&gt; sanitizes the response in case Gemma sneaks in backticks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The narration layer&lt;/strong&gt; (&lt;code&gt;narration_service.py&lt;/code&gt;) takes the Field Card text and sends it to ElevenLabs TTS (&lt;code&gt;eleven_turbo_v2_5&lt;/code&gt;, Rachel voice) as an audio stream. If there's no connection, it falls back to a procedurally generated E-major chime — an actual chord, not silence, so there's always audio feedback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The voice agent&lt;/strong&gt; is an ElevenLabs conversational widget embedded in the page. It loads after the Field Card appears, so the user reads what Gemma found, then taps to debrief out loud. The agent knows it's a field guide — it asks follow-up questions, sends you back outside if needed, never claims certainty.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The journal&lt;/strong&gt; is pure &lt;code&gt;localStorage&lt;/code&gt;. Base64 photo, full Field Card JSON, atelier completion status, your notes. It loads on startup so past entries are there when you return. Nothing goes to a server. Nothing is deleted unless you delete it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The offline layer&lt;/strong&gt; is a Service Worker that pre-caches the shell. If you analyze a photo while offline, it queues and syncs automatically when connection returns. The app works in a forest with no signal — the UI loads, past entries load, and the analyze call will retry when you're back.&lt;/p&gt;

&lt;p&gt;The backend is Flask + Gunicorn, deployed on Render's free tier via &lt;code&gt;render.yaml&lt;/code&gt;. Three environment variables: &lt;code&gt;GOOGLE_API_KEY&lt;/code&gt;, &lt;code&gt;ELEVENLABS_API_KEY&lt;/code&gt;, &lt;code&gt;ELEVENLABS_AGENT_ID&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;I built this from Antananarivo, Madagascar.&lt;/p&gt;

&lt;p&gt;Closed AI APIs aren't just expensive here — they're often inaccessible. Most require a credit card from a supported country. Payoneer as a transit layer, SWIFT, international transfer fees — all of that just to run &lt;code&gt;POST /analyze&lt;/code&gt;. And if the API goes down or the pricing changes, your app breaks.&lt;/p&gt;

&lt;p&gt;Gemma running through Google AI Studio changed the calculation. One Google account, one API key, no card required to get started. And because the model is open-weight, the honest path is clear: if Google AI Studio ever becomes a problem, you point the same &lt;code&gt;google-genai&lt;/code&gt; client at a local Ollama instance and nothing else changes. The model is swappable. The app doesn't have to die with a vendor decision.&lt;/p&gt;

&lt;p&gt;The offline design matters for the same reason. When I take this outside in a park with no signal — which is most of the time — the UI still loads, the journal still loads, the Service Worker still serves the shell. The analysis queues and fires when I'm back on Wi-Fi. The screen is the smallest part of the experience, which is exactly what the prompt asked for.&lt;/p&gt;

&lt;p&gt;Open innovation didn't make this &lt;em&gt;easier&lt;/em&gt;. It made it &lt;em&gt;possible&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;p&gt;Dut to some problem in my laptop, I couldn't use DevRelay. But here is my prompt: You are a senior full-stack developer.&lt;br&gt;
Design and generate the complete code for a fieldwork web application called "Nook" (with the tagline: Observe. Investigate. Create.). &lt;br&gt;
This project is an ecological  application designed  with the open-weight model Gemma 4 at its core framework.&lt;/p&gt;

&lt;p&gt;However, the generated code must be complete, production-grade, and immediately functional, before tokens run out.&lt;/p&gt;

&lt;p&gt;FRAMEWORK, RENDERING, AND PORT CONSTRAINTS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The backend application must strictly use FLASK&lt;/li&gt;
&lt;li&gt;The application must  run locally on its native default port: PORT 5000 (localhost:5000). &lt;/li&gt;
&lt;li&gt;The frontend must be served directly by Flask via its static and template folders, using only native HTML5 / CSS3 / Vanilla JavaScript (no separate Node.js frontend server).&lt;/li&gt;
&lt;li&gt;Provide a configuration file for Render for deployment on their free tier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI ENGINE (GEMMA 4 ):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The application's core logic depends on API execution or inference of the "gemma-4-31b-it" or "gemma-4-26b-a4b-it" multimodal model.&lt;/li&gt;
&lt;li&gt;You must use the official new &lt;code&gt;google-genai&lt;/code&gt; Python SDK to handle all backend AI operations.&lt;/li&gt;
&lt;li&gt;Configure the default model parameter to use "gemma-4-31b-it", butmake sure it reads from an environment variable &lt;code&gt;GEMMA_MODEL_ID&lt;/code&gt; (so the user can easily swap it to "gemma-4-26b-a4b-it" via the .env file).&lt;/li&gt;
&lt;li&gt;The backend must feature full validation and standard JSON parsing structures processing raw output string responses from Gemma safely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;USER STORY: &lt;br&gt;
The goal of Nook is to encourage the user to leave their screen and explore nature. &lt;br&gt;
This is the code  pipeline:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;OBSERVE: A paccessible mobile-first interface (capture="environment") with dark mode posibility). 
The user snaps or uploads a photo from their phone.&lt;/li&gt;
&lt;li&gt;ANALYZE: The Flask receives the image, validates the  type (jpeg, png, webp, gif), encodes it to base64 bytes, and directly queries the l Gemma 4 model using the google-genai client.
The prompt sent to Gemma MUST demand a JSON object . The returned JSON must contain (written in a cautious, naturalist tone, max 25 words per string):

&lt;ul&gt;
&lt;li&gt;"seen": 3 to 6 direct visual observations such as (color, shape, texture).&lt;/li&gt;
&lt;li&gt;"possible_identification": The possiblr identification might be still wrong, even if just rarely. It is better to state "possible", not confirming if not sure.&lt;/li&gt;
&lt;li&gt;"alternatives": 1 or 2 other plausible options of why something had became what it was when taken photos&lt;/li&gt;
&lt;li&gt;"hypotheses": 2 possible explanations regarding the state or origin of the found object&lt;/li&gt;
&lt;li&gt;"uncertain": What the photo cannot tell due to its limitations. The AI Asks further questions in the investigation_question&lt;/li&gt;
&lt;li&gt;"investigation_question": The AI asks further questions about the found objects for the AI to confirm hypothesis or suggestions, and helps people develop their observation and attention skills.&lt;/li&gt;
&lt;li&gt;"observation_mission": An action to do outside immediately without touching or disturbing nature, like following ants' paths to their anthill, or give a rabit a leaf, or caressing barks to feel the relief, etc...&lt;/li&gt;
&lt;li&gt;"atelier": A creative crafting task  that should be a concrete, safe action to do , based with the found objects (those can be a herbier with a clover, a drawing of a bark's patterns, a flower crown, a petal coloration, squirrel's best ohotoshoot, a christmas decoration made from pine cones, leaves, etc...).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;NARRATE: A Flask endpoint POST /narrate receives the card text and uses the ElevenLabs TTS API (Model: &lt;code&gt;eleven_turbo_v2_5&lt;/code&gt;, default Voice ID) to return a binar audio/mpeg stream. The JavaScript interface displays a "Field Card " button to fetch and play this audio stream directly in the browser.&lt;/li&gt;
&lt;li&gt;INVESTIGATE The interface integrates the official ElevenLabs conversational voice widget (&lt;code&gt;&amp;lt;elevenlabs-convai&amp;gt;&lt;/code&gt; loaded  via its script) by dynamically injecting the Agent ID. The user speaks to this voice guide in real-time to report their findings after returning from their outdoor mission.&lt;/li&gt;
&lt;li&gt;PRESERVE: A field journal saves the session locally (base64 photo, Field Card JSON, atelier completion status, and user text notes) into the browser's localStorage. A history of past journal entries must be displayed upon loading the application, fot the hapiness to find memories back and remember what was learned through the little travel outside;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;SECURITY AND ROBUSTNESS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Strict exception handling with clean Python logging&lt;/li&gt;
&lt;li&gt;Robust parser helper to sanitize Gemma's JSON string in case it contains accidental markdown backticks (

&lt;code&gt;json ...&lt;/code&gt;

).&lt;/li&gt;
&lt;li&gt;Full isolation of secrets using an environment file (.env) containing: GOOGLE_API_KEY, GEMMA_MODEL_ID, ELEVENLABS_API_KEY, ELEVENLABS_AGENT_ID, and optional ElevenLabs voice variables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;STYLE &amp;amp; LAYOUT:&lt;br&gt;
Make the web app present the theme as following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Artisanal Minimalism: Clean design without clutter.

&lt;ul&gt;
&lt;li&gt;Smart-Casual Tone: Low pressure, high intention. Cool attitude withpit forgettong the serious execution.&lt;/li&gt;
&lt;li&gt; Background: #0F0F11&lt;/li&gt;
&lt;li&gt; Primary Text &amp;amp; Headers: #F5F5F7&lt;/li&gt;
&lt;li&gt; Secondary Text &amp;amp; Metadata: #86868B&lt;/li&gt;
&lt;li&gt; Borders &amp;amp; Dividers: #2C2C2E&lt;/li&gt;
&lt;li&gt; Interactiveity and Hover State: #FFFFFF
Those are by default. But people should be able to choose among lots of color themes (blue, orange, purple, green, etc...) and light or dark theme.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;USER PROFILE:&lt;br&gt;
 Save everything (the user's color themes, options, and nature journal entries) directly inside the browser's memory, never on a distant database. This keeps their data safe and ensures the app works 100% offline.&lt;/p&gt;

&lt;p&gt;ONLINE/OFFLINE FUNCTIONALITY:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The app must work even with zero internet (like deep in the forest).&lt;/li&gt;
&lt;li&gt;Create a 'sw.js' file (Service Worker) so the app's pages and designs load offline.&lt;/li&gt;
&lt;li&gt;If the user takes a photo or finishes a task while offline, save it inside the browser's local memory immediately.&lt;/li&gt;
&lt;li&gt;As soon as the phone gets internet back, the app must automatically send those saved photos and notes to the Flask backend without making the user refresh the page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RESULTING JOURNAL:&lt;br&gt;
The result of PRESERVE user story: a personalized poster, or a little digital journal, according to the user's choices, contains all the result of the functionalities: the taken photo, the description, the possible causes of their state, cool artistic or useful things to craft from the shot objects.&lt;/p&gt;

&lt;p&gt;Generate all the necessary files for this application now, ready to be executed on port 5000.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma&lt;/strong&gt; — Gemma 4 (&lt;code&gt;gemma-4-31b-it&lt;/code&gt;) is the entire analysis engine. It receives the raw image bytes, returns a structured eight-field naturalist Field Card, and powers every section the user sees. Swappable to &lt;code&gt;gemma-4-26b-a4b-it&lt;/code&gt; via one environment variable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of ElevenLabs&lt;/strong&gt; — Two integrations: TTS narration of the Field Card via &lt;code&gt;eleven_turbo_v2_5&lt;/code&gt; (so the user can listen and go back outside), and the conversational Agent widget for real-time voice debrief when they return.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render&lt;/strong&gt; — Flask + Gunicorn deployed on Render's free tier. The &lt;code&gt;render.yaml&lt;/code&gt; defines the full service with environment variables. Auto-deploys from GitHub on every push.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Gemma Atlas</title>
      <dc:creator>RAKOTONDRAINIBE Rohiniaina Maria Grazia</dc:creator>
      <pubDate>Mon, 05 Oct 2026 06:58:47 +0000</pubDate>
      <link>https://dev.to/lonewolfnyx/gemma-atlas-1hk7</link>
      <guid>https://dev.to/lonewolfnyx/gemma-atlas-1hk7</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&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%2Frj6o3530lm839xc3kapc.jpg" 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%2Frj6o3530lm839xc3kapc.jpg" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Gemma Atlas&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An adaptive, private study architect and self-paced curriculum engine powered by Google's open Gemma 9B and 2B models.&lt;/p&gt;

&lt;p&gt;My younger siblings are homeschooled, and our mother is an English teacher. She designs their entire curriculum and teaches every class herself. But she also works at other institutions, which means my siblings are by themselves when she's not home to teach them.&lt;/p&gt;

&lt;p&gt;Even when my mother give them topics and chapters to research and to learn, my siblings struggled to find contents because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;they don't know where to start,&lt;/li&gt;
&lt;li&gt;they hesitate about what video or websites or document to trust and exploit for learning.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having lived through the exact same struggle myself, I built Gemma Atlas to give them what I wish I'd had.&lt;/p&gt;

&lt;p&gt;Gemma Atlas takes a topic name or any document — slides, lecture notes, PDFs, code files — and turns it into a complete, adaptive mastery roadmap powered by Gemma.&lt;/p&gt;

&lt;p&gt;The system provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Autonomous curriculum deconstruction:&lt;/strong&gt; Gemma analyzes the scope of the subject and generates a structured roadmap with chapters, sub-chapters, key notions, governing formulas, and exam traps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Universal document treatment:&lt;/strong&gt; Any file format (.pdf, .docx, .pptx, .txt, .md, code files) is parsed client-side and indexed into an in-memory TF-IDF vector store for grounded, source-anchored generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Student-profile-friendly content adaptation:&lt;/strong&gt; Each session is personalized to the student's academic level, learning style (Visual, Auditory, Kinesthetic, Reading, Writing, Fast-Paced like ADHD), cognitive conditions, free time, and exam deadline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5-Box Leitner spaced repetition:&lt;/strong&gt; Auto-generated flashcard decks with review intervals of 1, 3, 7, 14, and 30 days. Cards advance or reset based on recall, countering the forgetting curve.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crash Test exam arena:&lt;/strong&gt; Scenario-based multiple-choice quizzes that explain not only the right answer, but also the traps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dual-engine inference:&lt;/strong&gt; Runs with Cloud Gemma 9B endpoints via an Express backend, or fully offline in-browser with Gemma 2-2B loaded via WebGPU and WebLLM.
Every information about the users are stored on their phone, so no one can access those information except themselves.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, Gemma Atlas resolves the uncertainty of "where to start to learn this topic?" my siblings&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://drive.google.com/file/d/1n3mnPZX5-dKbbW8FCN-4aqKNBlsQW7kv/view?usp=drive_link" rel="noopener noreferrer"&gt;https://drive.google.com/file/d/1n3mnPZX5-dKbbW8FCN-4aqKNBlsQW7kv/view?usp=drive_link&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Here is the GitHub link of the Gemma Atlas Project&lt;br&gt;
&lt;a href="https://github.com/RoxyMaxy/Gemma-Atlas/" rel="noopener noreferrer"&gt;https://github.com/RoxyMaxy/Gemma-Atlas/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; React 19, TypeScript, Vite, Tailwind CSS, Lucide Icons, Recharts — with an Express + &lt;code&gt;tsx&lt;/code&gt; backend serving the &lt;code&gt;/api/session&lt;/code&gt; and &lt;code&gt;/api/chat&lt;/code&gt; routes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AI inference&lt;/strong&gt; runs through &lt;code&gt;@google/genai&lt;/code&gt;, cycling through a prioritized list of Gemma/Gemini Flash endpoints until one responds. &lt;br&gt;
The &lt;code&gt;/api/session&lt;/code&gt; route generates the structured study session (roadmap, concepts, flashcards, and quiz) as a single validated JSON payload. &lt;br&gt;
The &lt;code&gt;/api/chat&lt;/code&gt; route handles follow-up Q&amp;amp;A in streaming SSE mode. &lt;br&gt;
When the client requests local mode, the backend short-circuits and defers to &lt;code&gt;@mlc-ai/web-llm&lt;/code&gt;, which loads &lt;code&gt;gemma-2-2b-it-q4f16_1-MLC&lt;/code&gt; weights directly into the browser's GPU memory via WebGPU.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Document parsing&lt;/strong&gt; is ran client-side. &lt;br&gt;
Plain text and code files are read as UTF-8 streams. &lt;br&gt;
PDFs are scanned with binary regex patterns to extract BT...ET text objects. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Office formats are unzipped and traversed for XML text nodes (&lt;code&gt;&amp;lt;w:t&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;a:t&amp;gt;&lt;/code&gt;). &lt;br&gt;
Unrecognized format falls back to printable UTF-8 character extraction, so no file is ever rejected. &lt;br&gt;
Extracted content is chunked using 128-dimensional FNV-1a hash embeddings with cosine similarity retrieval, which grounds the Gemma prompt in the student's source material.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Leitner scheduler&lt;/strong&gt; lives in &lt;code&gt;StorageService&lt;/code&gt; and advances cards through five boxes based on recall. State is persisted in &lt;code&gt;localStorage&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For &lt;strong&gt;The design&lt;/strong&gt;, I used the MLH's website style, because I found it original and unique, and because I really enjoyed my path through this challenge, including the programming, the debugging and the solution seeking.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used the DevRelay on Antigravity, using Gemini 3.8 medium, and Google AI Studio for troubleshooting.&lt;/p&gt;

&lt;p&gt;Antigravity created the skeleton code and architecture. I coded the style layout myself, but it resulted in numerous bugs.&lt;br&gt;
Therefore, I used Google AI Studio to polish the syntaxes, correct my own codes, and compile the final result.&lt;/p&gt;
&lt;h2&gt;
  
  
  Challenges
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;My first tiny bug through this challenge was the prompt: usually, I would define every single detail myself, and since I have researched and prepared before constructing this project, I knew almost everything about this product. Therefore, I already knew how I would want it to look like and how it would work. But having to study at the same time and lead my team in our college projects, I kind of just typed the overall features for the constraints, even though I explained the role, the context and the task well. Outputs were already explained in detail for the project parts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The second problem was the syntaxes: I knew how to code the layouts, but I forgot some details and overlooked them (especially about the syntaxes and the animation) and it resulted on multiple bugs. I had to check all my errors myself, and when I didn't see any more, I finally used the Google AI Studio to check it out.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Getting Gemma to reliably produce large  JSON payloads (for the roadmap stages, flashcards, quizzes) without malformed output required strict schema enforcement in the prompt. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A silent fallback bug was returning generic stage names whenever the primary endpoint was slow; fixing it meant rebuilding the &lt;code&gt;/api/session&lt;/code&gt; route with a proper model cascade rather than a static fallback.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Running Gemma 2-2B in-browser via WebGPU required careful GPU adapter detection and graceful degradation for devices without hardware acceleration support.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Open Innovation Matters
&lt;/h2&gt;

&lt;p&gt;To me, young students shouldn't have their learning notes, cognitive profiles, and personal study habits uploaded to proprietary platforms: for security and policies, mostly, but also for the token limits and paid plans.&lt;br&gt;
Open-weight models running locally mean private inference with zero subscription cost. &lt;br&gt;
For students with unreliable internet or families who can't afford private tutoring, open innovation represents a huge advantage for access. A closed API would leave people with limited, incomplete content, or lots of hallucinations.&lt;/p&gt;

&lt;p&gt;Open innovation matters for my project, because it helps people widen their horizon and improve themselves by accessing to the most complete and detailed content possible. It represents a way for people to enjoy learning, access quality content with a more accurate, hallucination-reduced content. Hence, it helps people in their personal development.&lt;/p&gt;
&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;On the AI side, I learned that prompt architecture is its own discipline. Getting Gemma to autonomously size a curriculum rather than filling a fixed template required understanding how temperature, schema constraints, and instruction phrasing interact. For example, too much freedom gets the output generic, but if it's too rigid, it feels canned and kind of boring, hostile, even, for some people. Finding that balance through my own experiences taught me more about how language models actually behave than any theoretical reading had.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the engineering side, building client-side binary parsers for PDFs and Office XML gave me a real understanding of how those formats work. This knowledge is something I wouldn't have touched in a normal university project unless asked to. The same goes for implementing the vector index from scratch: writing FNV-1a hash embeddings and cosine similarity retrieval in plain TypeScript, rather than dropping in a library, forced me to actually understand what semantic search is doing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Learning about people's struggles and challenges in learning taught me about the diversity of people, different ways on how our brain works, and how science has managed to design and tailor different ways for everyone to learn at their pace but not to fall behind. and designing for short attention spans taught me that information architecture matters as much as content. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Building Gemma Atlas also taught me to pay more attention to details and be careful with my actions (like typing correct syntaxes).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And on a personal level, I learned that having a real motivation to build something for people you actually care about changes how you solve problems. I wouldn't have really thought about every detail of this project about this learning topic if I did not have a clear overview of my siblings' situation, even if I have experienced the same problems.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;I entered in the Best Use of Gemma, because I was curious about this AI. I've heard of it frequently, but never used it, and this challenge brang me to research and explore it's potential.&lt;br&gt;
Gemma is the core AI in my project.&lt;/p&gt;
&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;




&lt;div class="ltag-agent-session"&gt;
  &lt;div class="agent-session-header"&gt;
    
    &lt;span class="agent-session-tool-icon-badge" title="Gemini CLI"&gt;
&lt;/span&gt;
    &lt;span class="agent-session-title"&gt;Gemma Atlas: Adaptive Private Study Workspace Architecture&lt;/span&gt;
  &lt;/div&gt;

  &lt;div class="agent-session-scroll"&gt;

      &lt;div class="agent-session-message agent-session-user"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-user"&gt;
          You
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;I need a study workspace for my siblings. They need a full workspace that helps them master any topic they need, and they don't know what to start with. The workspace should be empathetic, adaptive and private, supporting Gemma 2 9B IT in the cloud and Gemma 2 2B IT locally offline.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;

  &lt;div class="agent-session-footer"&gt;
    &lt;span class="agent-session-meta"&gt;
        1 of 2 messages
          · some content was hidden by the author
    &lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Final Note
&lt;/h2&gt;

&lt;p&gt;I built Gemma Atlas for my siblings and my mother. She works hard enough, but when she's not home, they deserve something that meets them where they are, helps them move forward and ease the teachers' work.&lt;/p&gt;

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