<?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: Anurag Yadav</title>
    <description>The latest articles on DEV Community by Anurag Yadav (@akyadav).</description>
    <link>https://dev.to/akyadav</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%2F4160875%2F41604067-5fd7-4154-a5dd-ee0daa223594.png</url>
      <title>DEV Community: Anurag Yadav</title>
      <link>https://dev.to/akyadav</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/akyadav"/>
    <language>en</language>
    <item>
      <title>Sloth Digest: I Taught Gemma to Read My Group Chats So I Don’t Have To</title>
      <dc:creator>Anurag Yadav</dc:creator>
      <pubDate>Sun, 25 Oct 2026 09:36:03 +0000</pubDate>
      <link>https://dev.to/akyadav/sloth-digest-i-taught-gemma-to-read-my-group-chats-so-i-dont-have-to-1fe9</link>
      <guid>https://dev.to/akyadav/sloth-digest-i-taught-gemma-to-read-my-group-chats-so-i-dont-have-to-1fe9</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Sloth Digest is a small web app that reads your group chats so you don't have to.&lt;/p&gt;

&lt;p&gt;You paste in a noisy chat from WhatsApp, Slack, Telegram or email. A few seconds later you get three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A two-line summary&lt;/strong&gt; of what actually happened&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What needs you&lt;/strong&gt;, with the person and the exact deadline&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you can safely ignore&lt;/strong&gt; (good-morning messages, stickers, match banter)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also shows a rough "minutes saved" figure. It divides the words you skipped by an average reading speed of 200 words per minute, so treat it as an estimate.&lt;/p&gt;

&lt;p&gt;Anyone who has come back to 200 unread messages and had to scroll for the one line that said "pay by Saturday" gets to be a little lazier. That was the goal.&lt;/p&gt;

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

&lt;p&gt;Live demo: &lt;a href="https://sloth-digest.onrender.com" rel="noopener noreferrer"&gt;https://sloth-digest.onrender.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a &lt;strong&gt;Try a sample chat&lt;/strong&gt; button, so you can see a full result without pasting anything private. The sample is a made-up chat about a trip and a deadline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/NIsI54rqJQY" rel="noopener noreferrer"&gt;https://youtu.be/NIsI54rqJQY&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/ypunit757-prog/Sloth-Digest" rel="noopener noreferrer"&gt;https://github.com/ypunit757-prog/Sloth-Digest&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;The stack is deliberately small: a Node + Express server and a plain JavaScript frontend, with no framework and no build step.&lt;/p&gt;

&lt;p&gt;The open-source AI piece is &lt;strong&gt;Gemma&lt;/strong&gt;, Google's open-weight model. The server has one switch, &lt;code&gt;AI_PROVIDER&lt;/code&gt;, that decides how Gemma is run:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;On my laptop:&lt;/strong&gt; Gemma runs through &lt;strong&gt;Ollama&lt;/strong&gt; (&lt;code&gt;gemma3:4b&lt;/code&gt;). Inference is fully local.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In the deployed demo:&lt;/strong&gt; The same Gemma family is served through the &lt;strong&gt;Gemini API&lt;/strong&gt;, and the app is hosted on &lt;strong&gt;Render&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The route handler is the same either way. Only the model call changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;PROVIDER&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gemini&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;askGemini&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;buildPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;askOllama&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;buildPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;digest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extractJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things I learned along the way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemma on the Gemini API takes no system instruction.&lt;/strong&gt; I put the rules in the prompt itself instead, and used one prompt for both providers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Small models don't always return clean JSON.&lt;/strong&gt; The server strips markdown fences, pulls out the JSON object, and validates the shape before it reaches the UI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The browser never sees a key.&lt;/strong&gt; It only talks to &lt;code&gt;/api/*&lt;/code&gt;, so the Gemini key lives in a Render environment variable. The server also rate-limits requests and caps input at 12,000 characters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slowness is a feature.&lt;/strong&gt; The loader is a slow-moving bar, in keeping with the sloth theme.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Group chats are some of the most private text we have. They hold family plans, money, health news and gossip. Pasting that into a closed API means trusting a company with it.&lt;/p&gt;

&lt;p&gt;Because Gemma has open weights, I could build the same app so it runs &lt;strong&gt;entirely on my own machine&lt;/strong&gt;. With Ollama it works offline, costs nothing per run, and sends nothing anywhere. A closed API wouldn't let me make that promise.&lt;/p&gt;

&lt;p&gt;Open weights also gave me &lt;strong&gt;freedom to move&lt;/strong&gt;. The same model family runs locally and on a hosted API, and I switched between them with one environment variable. If a model improves or a price changes, I can swap it without rewriting the app.&lt;/p&gt;

&lt;p&gt;I'll be honest about the trade-off: my hosted demo calls Gemma through an API, so the demo is not private the way local mode is. The local mode is the privacy-first version, and the hosted one is there so you can try it quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lazy Payoff
&lt;/h2&gt;

&lt;p&gt;The app's own estimate for the sample chat (about 120 words) is roughly half a minute of reading saved. That's small for one chat, but it adds up over a busy week of active group chats.&lt;/p&gt;

&lt;p&gt;[&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 is the core of the app. It runs locally through Ollama and is served through the Gemini API for the hosted demo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render:&lt;/strong&gt; The app is deployed on Render with a &lt;code&gt;render.yaml&lt;/code&gt; blueprint, so the whole deploy is one click plus an API key.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>ListingLoom: an Etsy and eBay listing writer that runs on an open model I control</title>
      <dc:creator>Anurag Yadav</dc:creator>
      <pubDate>Sun, 18 Oct 2026 00:13:28 +0000</pubDate>
      <link>https://dev.to/akyadav/listingloom-an-etsy-and-ebay-listing-writer-that-runs-on-an-open-model-i-control-2he8</link>
      <guid>https://dev.to/akyadav/listingloom-an-etsy-and-ebay-listing-writer-that-runs-on-an-open-model-i-control-2he8</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12"&gt;Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;ListingLoom is a listing writer for small sellers on Etsy and eBay. You describe what you made (product, materials, scent or style, a few details, and what it cost you), pick a voice, and it returns a title, a description, tags, and a suggested price range.&lt;/p&gt;

&lt;p&gt;The person who would pay for it is the maker who lists a few new items every week and hates the writing part. Anyone who sells candles, ceramics, prints or resale finds knows the routine: you finish the product, then spend twenty minutes staring at an empty description box and guessing which tags buyers search for.&lt;/p&gt;

&lt;p&gt;The price suggestion is what I think makes it more than a text generator. Most sellers price by feel and forget that marketplace fees take a real bite. ListingLoom takes your cost to make, subtracts estimated fees for the marketplace you chose, and shows a range that leaves you roughly 30 to 45 percent profit.&lt;/p&gt;

&lt;p&gt;There are three plans on the pricing section: Free for people who self-host, Seller at $9 a month for a hosted version with saved voices and listing history, and Studio at $29 a month for bulk CSV uploads and a model tuned on a shop's best sellers. The paid plans are a waitlist for now, and the form on the page collects emails.&lt;/p&gt;

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

&lt;p&gt;Live app:  &lt;a href="https://listingloom.onrender.com" rel="noopener noreferrer"&gt;https://listingloom.onrender.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[Video demo: &lt;a href="https://youtu.be/0fweN4gcJL8" rel="noopener noreferrer"&gt;https://youtu.be/0fweN4gcJL8&lt;/a&gt;]&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/ypunit757-prog/ListingLoom" rel="noopener noreferrer"&gt;https://github.com/ypunit757-prog/ListingLoom&lt;/a&gt; &lt;/p&gt;

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

&lt;p&gt;The app is a small Node and Express server with a plain HTML, CSS and JavaScript front end. There is one real dependency, Express.&lt;/p&gt;

&lt;p&gt;The writing is handled by an open-weight model, Gemma [confirm the exact model you ran, for example gemma3:1b], through a standard OpenAI-style chat endpoint. The server only needs three settings: a base URL, a model name and an optional key. That means the same code works with Ollama on a laptop, a model server on a private network, or a hosted provider that serves open models.&lt;/p&gt;

&lt;p&gt;A few details that took more work than I expected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Structured output from a small model.&lt;/strong&gt; The server asks for a single JSON object, then pulls the first object out of the reply and checks it. It also trims the title to the marketplace's limit (140 characters on Etsy, 80 on eBay) and caps the number of tags.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No made-up facts.&lt;/strong&gt; The system prompt tells the model to use only what the seller provided and to avoid inventing sizes, certifications or health claims. A candle listing that claims it is "allergy safe" can cause real trouble, so I kept the model on a short leash.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A fallback that is honest about itself.&lt;/strong&gt; If no model is connected, or the model call fails, the server returns a simple template draft instead of an error. The result card says which one wrote the listing, either the model's name or "Template draft", so a seller is never told a template is AI output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The price math lives on the server.&lt;/strong&gt; It is deterministic, not generated by the model. The fee percentages sit in one table and are estimates, so they need checking against current marketplace fees.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Basic protection.&lt;/strong&gt; Inputs are length-limited, and the endpoints have a small rate limiter.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I deployed it as a web service on Render, with the model settings kept in environment variables so the key never touches the repository.&lt;/p&gt;

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

&lt;p&gt;A listing writer only works as a business if two things hold, and an open model helps with both.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Margins.&lt;/strong&gt; A closed API charges per token. At $9 a month, a heavy user who generates dozens of listings and regenerates the ones they dislike can quietly cost more than they pay. With an open-weight model I control, the cost of the thousandth listing is the same as the first, so a low price stays viable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Privacy.&lt;/strong&gt; A seller's cost of goods, supplier names and unreleased designs are the most sensitive things they own. With an open model on a server I control, none of that has to be sent to a third-party AI company. That is a practical selling point for a small business, not just a principle.&lt;/p&gt;

&lt;p&gt;It also gives me room to change things. Swapping the model is a two-line settings change, and the Studio plan idea (a model tuned on a shop's own best-selling listings) is only possible because the weights are open. I can't fine-tune a closed API on a customer's catalogue the way I can an open model.&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;: the writing is done by Gemma running behind an open chat endpoint. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render&lt;/strong&gt;: the app is deployed as a Render web service at &lt;a href="https://listingloom.onrender.com" rel="noopener noreferrer"&gt;https://listingloom.onrender.com&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Pocket Trail: an open-weight model writes you a walk, then tells you to close the tab</title>
      <dc:creator>Anurag Yadav</dc:creator>
      <pubDate>Sat, 10 Oct 2026 15:25:22 +0000</pubDate>
      <link>https://dev.to/akyadav/pocket-trail-an-open-weight-model-writes-you-a-walk-then-tells-you-to-close-the-tab-2182</link>
      <guid>https://dev.to/akyadav/pocket-trail-an-open-weight-model-writes-you-a-walk-then-tells-you-to-close-the-tab-2182</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;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Most "get outside" apps want you to stay inside them. &lt;strong&gt;Pocket Trail&lt;/strong&gt; does the opposite.&lt;/p&gt;

&lt;p&gt;You tell it how long you have and what kind of walk you want: wander, wildlife, plants, quiet or brisk. It checks today's weather, daylight and moon phase, and an open-weight model writes a one-page &lt;strong&gt;trail card&lt;/strong&gt;. The card has a title, three or four physical steps, three things to notice, what to bring, and a &lt;strong&gt;turn-back time&lt;/strong&gt;. You can print it, copy it as text, or start &lt;strong&gt;walk mode&lt;/strong&gt;, which shows only one countdown and the current step.&lt;/p&gt;

&lt;p&gt;The first thing on the page is not a button. It is a clock counting how long you have been on the screen, with a goal of &lt;strong&gt;90 seconds&lt;/strong&gt;. If you linger, it turns red. The success metric is how fast you stop using the app.&lt;/p&gt;

&lt;p&gt;Other features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Daylight bar:&lt;/strong&gt; a drawn arc from sunrise to sunset with your walk highlighted, so you can see how much light you have.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Notice checklist:&lt;/strong&gt; tick things off as you spot them, and the count goes into your log.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outings log:&lt;/strong&gt; outings, day streak, minutes outside, and your average screen time before leaving. It stays in your own browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is for anyone who has said "I should go for a walk" and then spent twenty minutes picking the perfect route.&lt;/p&gt;

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

&lt;p&gt;Short video of Pocket Trail running with Gemma 3 1B on my machine (the card footer shows which model wrote each card):&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/di2v5ymkGmM" width="710" height="399"&gt;
  &lt;/iframe&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/ypunit757-prog" rel="noopener noreferrer"&gt;
        ypunit757-prog
      &lt;/a&gt; / &lt;a href="https://github.com/ypunit757-prog/pocket-trail" rel="noopener noreferrer"&gt;
        pocket-trail
      &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;Pocket Trail&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;An open-weight model writes you a one-page walk card (print it or copy it), then gets out of your way
The app times its own screen use and aims to be done in under 90 seconds.&lt;/p&gt;
&lt;p&gt;Built for the DEV Hacktoberfest Open-Source AI Challenge, Week 1: Touch Grass.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Context in code, not in the model:&lt;/strong&gt; weather, sunset, moon phase and season come from Open-Meteo (free, no key) and plain Python.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 3 1B (open weights)&lt;/strong&gt; runs on the same Render service through Ollama and writes the card as JSON.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Guardrails in code:&lt;/strong&gt; thunderstorms or under 35 min of daylight return "Not today" and no card. The turn-back time is capped 20 min before sunset. Model output is validated and step times are rescaled to your time budget.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline rules fallback:&lt;/strong&gt; if the model is unreachable, a deterministic generator still returns a card, and the card…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ypunit757-prog/pocket-trail" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Run it yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
ollama pull gemma3:1b &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ollama serve   &lt;span class="c"&gt;# optional: without it you get an offline fallback&lt;/span&gt;
uvicorn app.main:app &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 3 1B (open weights)&lt;/strong&gt; runs locally through &lt;strong&gt;Ollama&lt;/strong&gt; and writes the card as JSON.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FastAPI&lt;/strong&gt; serves one API route and one static page, with no front-end framework and no build step.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open-Meteo&lt;/strong&gt; supplies weather and sunset. Moon phase and season are computed in Python.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The design choice I care most about: &lt;strong&gt;the model only writes the prose. Code decides everything that could hurt you.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A thunderstorm nearby, or less than 35 minutes of daylight left, returns "Not today" and no card at all.&lt;/li&gt;
&lt;li&gt;The turn-back time is computed in code and capped 20 minutes before sunset.&lt;/li&gt;
&lt;li&gt;Gear advice (rain shell, hat, warm layer) comes from the weather numbers, not the model.&lt;/li&gt;
&lt;li&gt;Step times are rescaled so they add up to the real walk length.&lt;/li&gt;
&lt;li&gt;If the model is unreachable, a deterministic offline generator still returns a card, and the footer says which one wrote it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What I learned from a 1B model.&lt;/strong&gt; My first Gemma cards failed my own validation. The model returned steps like &lt;code&gt;{"do": 1, "min": 10}&lt;/code&gt;, numbers where instructions should be. I fixed it by putting a worked example in the prompt and allowing one retry. Later it described crisp autumn air on a hot day, and a moonlit sky at noon, so I added a "Feels" word to the prompt and code checks that reject cold-weather wording when it is warm and any moon mention in a daytime card.&lt;/p&gt;

&lt;p&gt;Here is a card Gemma wrote while I was testing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Autumnal Echoes&lt;/strong&gt;: &lt;em&gt;The sunlight filters through the thinning leaves, painting the forest floor in gold.&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Walk slowly towards a small, moss-covered stream.&lt;/li&gt;
&lt;li&gt;Listen closely; you hear the faint chirping of robin chicks.&lt;/li&gt;
&lt;li&gt;Observe a busy ant colony marching across a fallen log.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is not perfect (robin chicks in October is a spring detail), and that is the point. A small model makes small slips, so the code owns timing, safety and gear, and the model owns the wording.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;No API key, no meter.&lt;/strong&gt; The model runs on my own laptop, so there is no key to leak and no usage bill behind a free tool.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;My location stays with me.&lt;/strong&gt; Generation happens locally. The only thing that leaves is a latitude and longitude sent to the public Open-Meteo weather API, and I do not store it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I can change how it behaves.&lt;/strong&gt; The model is one environment variable (&lt;code&gt;LLM_MODEL&lt;/code&gt;), and any OpenAI-compatible server works. I could swap in another open model or fine-tune one on local trail knowledge without asking anyone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I could see the failures.&lt;/strong&gt; Because I run the model myself, I read its raw output when it went wrong and fixed the prompt and the guardrails, which a closed API that hides retries would not have let me do as easily.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The honest downside:&lt;/strong&gt; a 1B model is less inventive than a frontier one. For a card with a 25-word limit per item, that trade is fine.&lt;/li&gt;
&lt;/ol&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 3 1B runs locally through Ollama and writes every card in the demo video.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Saathi - a help application for my friend</title>
      <dc:creator>Anurag Yadav</dc:creator>
      <pubDate>Mon, 05 Oct 2026 07:12:23 +0000</pubDate>
      <link>https://dev.to/akyadav/saathi-a-help-application-2o8p</link>
      <guid>https://dev.to/akyadav/saathi-a-help-application-2o8p</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;Saathi is a study companion built around one person's own notes. You add your notes. It writes quiz questions from them, asks "how sure are you?" before you answer, works out &lt;em&gt;why&lt;/em&gt; a wrong answer was wrong, brings each question back just before you would forget it, and at the end of the week writes a short letter about how things went, in the way you like to be spoken to.&lt;/p&gt;

&lt;p&gt;I built it for &lt;strong&gt;[[Rahul Kumar]]&lt;/strong&gt;, [[He is my classmate]]. [[He was often struggles to evaluate   him during exam time ]]&lt;/p&gt;

&lt;p&gt;A chatbot answers from the whole internet. [[Rahul Kumar]] does not need the internet's version of chapter 4. They need to find out what &lt;em&gt;they&lt;/em&gt; do not understand about &lt;em&gt;their&lt;/em&gt; notes. So Saathi works only from their notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Grounded questions only.&lt;/strong&gt; Every generated question must pass a check (four distinct options, and the right answer has to appear in the source passage) before it is saved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidence matters.&lt;/strong&gt; A wrong answer you felt sure about is the most valuable signal, so it hurts the card's schedule the most and is called out in the letter.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mistakes get a reason.&lt;/strong&gt; The model names the likely misunderstanding behind that specific wrong choice, and the tags are counted over the week.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The letter only uses true numbers.&lt;/strong&gt; It is written by the model but from facts computed in SQL.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;[[Live link: &lt;a href="https://saathi-1vua.onrender.com" rel="noopener noreferrer"&gt;https://saathi-1vua.onrender.com&lt;/a&gt;. username - admin , password - Hello@123]]&lt;/p&gt;

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

&lt;p&gt;[[&lt;/p&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/ypunit757-prog" rel="noopener noreferrer"&gt;
        ypunit757-prog
      &lt;/a&gt; / &lt;a href="https://github.com/ypunit757-prog/Saathi" rel="noopener noreferrer"&gt;
        Saathi
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      An offline study companion, built for one person
    &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;Saathi&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;An offline study companion, built for one person.&lt;/p&gt;

&lt;p&gt;Saathi turns a friend's &lt;strong&gt;own notes&lt;/strong&gt; into quiz questions, asks how sure they are before they answer, works out &lt;em&gt;why&lt;/em&gt; a wrong answer was wrong, schedules each question for the moment they are about to forget it, and writes a short weekly letter in their own style of language. It runs an open-weight model (Gemma by default) through &lt;a href="https://ollama.com" rel="nofollow noopener noreferrer"&gt;Ollama&lt;/a&gt; on a laptop. Nothing is sent anywhere.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Built for the DEV Hacktoberfest Weekend Challenge, "Build for a Friend" (Oct 2 to 5, 2026). All code in this repo was started inside that window.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why it is shaped this way&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Their notes, not the internet.&lt;/strong&gt; Questions are written only from the notes you add, and every generated question must pass a grounding check (the right answer has to appear in the source passage) before it is saved. Small models make things up; this…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ypunit757-prog/Saathi" 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;&lt;strong&gt;The model.&lt;/strong&gt; Gemma, an open-weight model from Google. Saathi has three ways to reach it, chosen by one environment variable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ollama&lt;/code&gt;: Gemma (&lt;code&gt;gemma3:4b&lt;/code&gt;, or any Gemma you have pulled) on the laptop through Ollama. Nothing leaves the machine.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cloud&lt;/code&gt;: hosted Gemma 4 (&lt;code&gt;gemma-4-31b-it&lt;/code&gt;) through the Gemini API. This is what the live demo uses.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mock&lt;/code&gt;: a deterministic stand-in so the app and its 45 tests run with no model at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Saathi talks to the model over plain HTTP, so there is no SDK between my code and the model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack.&lt;/strong&gt; Python and Flask, one SQLite file, plain HTML/CSS/JS with no CDN and no framework. Hosted on &lt;strong&gt;Render&lt;/strong&gt; as a web service with a persistent disk, started with gunicorn. A password (&lt;code&gt;SAATHI_PASSWORD&lt;/code&gt;) protects the public URL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Four ideas that make it feel like a tutor, not a quiz generator&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Grounded questions.&lt;/em&gt; The model returns JSON and I validate it:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;   &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tokenize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
   &lt;span class="n"&gt;ans&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tokenize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;ans&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ans&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;   &lt;span class="c1"&gt;# the model invented it; drop the question
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Confidence changes the schedule.&lt;/em&gt; Standard SM-2 only knows right or wrong. Saathi also asks whether you were sure. Wrong-and-sure scores 0, wrong-and-unsure 1, and right-but-guessing gets a shorter gap than right-and-sure.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Every mistake gets a reason.&lt;/em&gt; A second request asks for the misunderstanding behind that wrong choice, so the right/wrong feedback stays instant.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;The letter only uses true numbers.&lt;/em&gt; The prompt forbids inventing anything outside the facts object.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Retrieval.&lt;/strong&gt; "Ask my notes" uses BM25 in pure Python (plus embeddings when a local embedding model exists). If the notes do not hold the answer, Saathi says so. Optionally, the learner can tick "Also search the web" and web results are labelled as such.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monitoring the agents.&lt;/strong&gt; Each task is a named agent (&lt;code&gt;Saathi Quiz Writer&lt;/code&gt;, &lt;code&gt;Misconception Diagnoser&lt;/code&gt;, &lt;code&gt;Notes Assistant&lt;/code&gt;, &lt;code&gt;Letter Writer&lt;/code&gt;) traced with Sentry's agent tracing: every model call records model, tokens and latency. Prompts and notes are not sent to Sentry unless I turn that on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Voice.&lt;/strong&gt; The weekly letter can be read aloud with ElevenLabs. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comparing models on the real job.&lt;/strong&gt; &lt;code&gt;bench/benchmark.py&lt;/code&gt; measures how often each model returns valid JSON and how many questions survive validation:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;model&lt;/th&gt;
&lt;th&gt;json_ok&lt;/th&gt;
&lt;th&gt;questions asked&lt;/th&gt;
&lt;th&gt;kept after validation&lt;/th&gt;
&lt;th&gt;sec/chunk&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;[[gemma3:1b]]&lt;/td&gt;
&lt;td&gt;[[ ]]&lt;/td&gt;
&lt;td&gt;[[ ]]&lt;/td&gt;
&lt;td&gt;[[ ]]&lt;/td&gt;
&lt;td&gt;[[ ]]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[[gemma3:4b]]&lt;/td&gt;
&lt;td&gt;[[ ]]&lt;/td&gt;
&lt;td&gt;[[ ]]&lt;/td&gt;
&lt;td&gt;[[ ]]&lt;/td&gt;
&lt;td&gt;[[ ]]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;[[Run &lt;code&gt;python bench/benchmark.py gemma3:1b gemma3:4b&lt;/code&gt; yourself and paste the real numbers. Delete this table if you do not run it.]]&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Their study history is private.&lt;/strong&gt; It is a record of everything someone does not understand yet. Because Gemma is open-weight, Saathi can run on Rahul kumar's own laptop and nothing has to leave it. The hosted demo is a deliberate trade-off, and it is the same code with one setting changed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I could shape it.&lt;/strong&gt; I could swap models when a small one was too slow, validate and discard its output, and rewrite the prompts so Saathi talks the way Rahul kumar talks .&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It works when the internet does not.&lt;/strong&gt;  A local model does not care.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost.&lt;/strong&gt; Spaced repetition means thousands of small questions. Per-token pricing turns "study a bit more" into a bill; a local open model does not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not locked in.&lt;/strong&gt; The hosted backend can also be any OpenAI-compatible endpoint, so moving from Google to a GPU server I run myself is a settings change, not a rewrite.&lt;/li&gt;
&lt;/ul&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%2F4mlwfqdem6fbj985wlpb.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%2F4mlwfqdem6fbj985wlpb.png" alt=" " width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

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