<?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: Harsh Verma</title>
    <description>The latest articles on DEV Community by Harsh Verma (@harshv).</description>
    <link>https://dev.to/harshv</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%2F4160402%2F7c9e767c-10df-4aa6-9eb0-9aa2be2e91d2.jpg</url>
      <title>DEV Community: Harsh Verma</title>
      <link>https://dev.to/harshv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/harshv"/>
    <language>en</language>
    <item>
      <title>Sloth-digest: two lines a morning instead of 300 unread WhatsApp messages</title>
      <dc:creator>Harsh Verma</dc:creator>
      <pubDate>Sun, 25 Oct 2026 12:32:32 +0000</pubDate>
      <link>https://dev.to/harshv/sloth-digest-two-lines-a-morning-instead-of-300-unread-whatsapp-messages-57g6</link>
      <guid>https://dev.to/harshv/sloth-digest-two-lines-a-morning-instead-of-300-unread-whatsapp-messages-57g6</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;I wake up to a flatmates group with 40 messages, a family group with 120, and a college group I stopped reading in August. Somewhere in there is the one message that actually needs me: "can you be home Saturday morning for the wifi guy?"&lt;/p&gt;

&lt;p&gt;sloth-digest reads WhatsApp chat exports and gives me two lines per chat each morning:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What happened.&lt;/li&gt;
&lt;li&gt;What I need to do, or "Nothing for you."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It runs on a timer at 7am, so the digest is already waiting by the time I get up. The model runs on my laptop. My chats never go anywhere.&lt;/p&gt;

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

&lt;p&gt;A fake flatmates chat goes in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;24/10/26, 21:02 - Asha: rent is due monday, everyone send me 9k by sunday pls
24/10/26, 21:05 - Ravi: done
24/10/26, 21:30 - Meera: wifi is down again, I called the ISP, tech comes saturday 10am
24/10/26, 21:31 - Meera: someone needs to be home for that
24/10/26, 22:10 - Ravi: not me, I'm out saturday
24/10/26, 22:40 - Asha: @Harsh can you be home sat morning?
24/10/26, 23:15 - Meera: also we're out of dish soap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And this comes out, as a desktop notification and in &lt;code&gt;digests/2026-10-25.md&lt;/code&gt;. This is the raw output, junk prefix included:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## Flatmates (7 new)
1.  Aft: Rent is due Monday, everyone needs to send 9k by Sunday.
2.  Harsh: Be home Saturday morning.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Run it again without a new export and it says &lt;code&gt;Nothing new.&lt;/code&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/harshverma27" rel="noopener noreferrer"&gt;
        harshverma27
      &lt;/a&gt; / &lt;a href="https://github.com/harshverma27/sloth-digest" rel="noopener noreferrer"&gt;
        sloth-digest
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Two-line morning digest of WhatsApp chats, summarised by a local model via Ollama
    &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;sloth-digest&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Group chats move faster than I do. This reads WhatsApp chat exports and gives me two lines per chat each morning: what happened, and whether anyone needs me. A small model runs locally through Ollama, so the chats never leave my laptop.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Setup&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Install &lt;a href="https://ollama.com" rel="nofollow noopener noreferrer"&gt;Ollama&lt;/a&gt; and pull a small model:&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;ollama pull gemma3:1b&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;No pip installs. The script only uses the Python standard library.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Use&lt;/h2&gt;
&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;In WhatsApp: open a chat, then &lt;strong&gt;More &amp;gt; Export chat &amp;gt; Without media&lt;/strong&gt;. Drop the &lt;code&gt;.txt&lt;/code&gt; into &lt;code&gt;inbox/&lt;/code&gt;. On iOS you get a zip; unzip it and rename &lt;code&gt;_chat.txt&lt;/code&gt; to the chat's name.&lt;/li&gt;
&lt;li&gt;Run it:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;python3 digest.py&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You get a notification, plus &lt;code&gt;digests/YYYY-MM-DD.md&lt;/code&gt;. &lt;code&gt;state.json&lt;/code&gt; remembers how many messages it has already seen in each chat, so re-exporting the same chat tomorrow only summarises what's new.&lt;/p&gt;

&lt;p&gt;Set &lt;code&gt;ME&lt;/code&gt; at the top of &lt;code&gt;digest.py&lt;/code&gt; to your name as it appears in chats, so…&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/harshverma27/sloth-digest" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


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

&lt;p&gt;The whole thing is about 100 lines of Python with no dependencies outside the standard library. The pieces:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parsing.&lt;/strong&gt; WhatsApp has no local API, but every phone can export a chat as a &lt;code&gt;.txt&lt;/code&gt;. The catch is that Android and iOS write different formats, and newer versions sneak invisible Unicode in (a narrow no-break space before PM, a left-to-right mark before media lines):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Android: 12/10/26, 22:14 - Name: msg
iOS:     [12/10/26, 10:14:05 PM] Name: msg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One regex matches the timestamp prefix for both. If the rest of the line has &lt;code&gt;Name:&lt;/code&gt;, it's a message. If it doesn't, it's a system notice ("Asha changed the group name") and gets dropped. Lines with no timestamp are the continuation of a multi-line message. Media placeholders like &lt;code&gt;&amp;lt;Media omitted&amp;gt;&lt;/code&gt; and &lt;code&gt;image omitted&lt;/code&gt; are thrown away.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Only new messages.&lt;/strong&gt; My first instinct was to store the last-seen timestamp. Then I remembered WhatsApp dates are DD/MM or MM/DD depending on your phone's locale, and there's no way to tell &lt;code&gt;03/04/26&lt;/code&gt; apart. So I stopped parsing dates entirely. Every export contains the full history, which means I just store how many messages each chat had last time in &lt;code&gt;state.json&lt;/code&gt;. Everything past that count is new. If the count shrinks, the file was replaced, so it starts over.&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;new_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;msgs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msgs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;seen&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;msgs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The model.&lt;/strong&gt; Gemma 3 1B, running in &lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt;. The script POSTs to &lt;code&gt;localhost:11434/api/chat&lt;/code&gt; with &lt;code&gt;urllib&lt;/code&gt;, a low temperature, and a bigger context window than Ollama's default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Telling the model who "me" is.&lt;/strong&gt; My first run on the flatmates chat returned "Nothing for you." even though someone had @-mentioned me by name. The prompt said "what needs my attention" and the model had no idea who I was. Adding one setting fixed 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;ME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Harsh&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;PROMPT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You summarise a group chat for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, who didn&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t read it. Reply with exactly two lines:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1. What happened: key topics and decisions.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2. What &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; needs to do: anything addressed to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; or @&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, and asks aimed at everyone. &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Write &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Nothing for you.&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; if none.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No preamble, no extra lines.&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;After that it caught the Saturday ask in three out of three fresh runs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scheduling.&lt;/strong&gt; A systemd user timer with &lt;code&gt;Persistent=true&lt;/code&gt;, so if the laptop is asleep at 7am it runs the moment I open the lid. The README has the two unit files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tests.&lt;/strong&gt; &lt;code&gt;test_digest.py&lt;/code&gt; checks the parser against Android and iOS samples (including the invisible characters and a multi-line message) and checks the new-message count. It runs without Ollama.&lt;/p&gt;

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

&lt;p&gt;Group chats are some of the most private text I have. Flatmates arguing about rent, family health updates, friends venting. Sending all of that to a hosted API every night so it can tell me "rent is due" is a bad trade. With an open-weight model running locally, the text goes from a file on my disk to a process on my machine and back. That's the whole data flow.&lt;/p&gt;

&lt;p&gt;It also costs nothing. A closed API would bill me every morning forever for a summary of my own messages. Gemma 3 1B is an 815 MB download, and after that it's free and works on a train with no signal.&lt;/p&gt;

&lt;p&gt;And I can swap the model. A 1B model is fast but rough: you can see it start a line with "Aft:" in the demo above, and it doesn't always put "asks for everyone" in line 2. When that annoys me enough, I &lt;code&gt;ollama pull&lt;/code&gt; a bigger model and change one string. No new account, no new pricing page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Exporting is still one tap per chat. WhatsApp doesn't let local apps read messages, and I didn't want to go near unofficial WhatsApp Web clients that log into your account.&lt;/li&gt;
&lt;li&gt;Only the newest 400 new messages per chat go to the model. That's plenty for one night. A big group after a week away gets trimmed.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Best Use of Gemma: Gemma 3 1B is the model doing the summarising, running locally through Ollama.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Listing Writer: Etsy and eBay listings from a local open model</title>
      <dc:creator>Harsh Verma</dc:creator>
      <pubDate>Tue, 13 Oct 2026 17:23:12 +0000</pubDate>
      <link>https://dev.to/harshv/listing-writer-etsy-and-ebay-listings-from-a-local-open-model-1h51</link>
      <guid>https://dev.to/harshv/listing-writer-etsy-and-ebay-listings-from-a-local-open-model-1h51</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;Listing Writer makes an Etsy or eBay listing from a few notes about a product. It gives you a title, a description, and tags.&lt;/p&gt;

&lt;p&gt;Small sellers spend a lot of time on listings. Twenty new candles means twenty new titles and descriptions. This tool does that work in seconds.&lt;/p&gt;

&lt;p&gt;Small sellers who list many items will pay for this. They do not want a monthly fee for each listing. They also do not want to send their product data to a server that they do not control. A one-time price for a tool on their own laptop is a better fit.&lt;/p&gt;

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

&lt;p&gt;Input: "Handmade soy candle, lavender and vanilla, 200g tin, 40 hour burn time, cotton wick"&lt;/p&gt;

&lt;p&gt;Output title: &lt;strong&gt;Lavender &amp;amp; Vanilla Soy Candle, 200g&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Output tags: soy candle, lavender candle, vanilla candle, handmade candle, 40 hour burn, cotton wick&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/harshverma27" rel="noopener noreferrer"&gt;
        harshverma27
      &lt;/a&gt; / &lt;a href="https://github.com/harshverma27/listing-writer" rel="noopener noreferrer"&gt;
        listing-writer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Etsy and eBay listing writer that runs locally on Gemma via Ollama
    &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;Listing Writer&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Type a few notes about something you're selling and get an Etsy or eBay listing back: a search-friendly title, a description, and tags. It runs on your own computer with Google's open-weight Gemma model through Ollama, so your product notes never leave your machine and there's no per-listing API bill.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Run it&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;You need Python 3 and &lt;a href="https://ollama.com" rel="nofollow noopener noreferrer"&gt;Ollama&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;ollama pull gemma3:1b&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;python3 app.py&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Then open &lt;a href="http://localhost:8000" rel="nofollow noopener noreferrer"&gt;http://localhost:8000&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The first listing takes a few extra seconds while Ollama loads the model. After that it takes 5 to 15 seconds on a laptop CPU.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Use a bigger model&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;gemma3:1b&lt;/code&gt; is small enough for almost any laptop. If you have the RAM, a bigger model writes better copy:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;ollama pull gemma3:4b&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;MODEL=gemma3:4b python3 app.py&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Other settings: &lt;code&gt;OLLAMA_URL&lt;/code&gt; (default &lt;code&gt;http://localhost:11434&lt;/code&gt;) and &lt;code&gt;PORT&lt;/code&gt; (default &lt;code&gt;8000&lt;/code&gt;).&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;code&gt;app.py&lt;/code&gt; is a small standard-library web server. It sends the notes to…&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/harshverma27/listing-writer" 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 app uses Gemma 3 1B. Gemma is an open-weight model from Google. Ollama runs the model on my laptop CPU. One listing takes 5 to 15 seconds.&lt;/p&gt;

&lt;p&gt;The app is a small Python web server and one HTML page. It uses only the Python standard library.&lt;/p&gt;

&lt;p&gt;Ollama makes the model reply in a fixed JSON format with a title, a description, and tags. Then the Python code applies the rules of each marketplace. For example, an Etsy title can have a maximum of 140 characters. An eBay title can have a maximum of 80 characters.&lt;/p&gt;

&lt;p&gt;I had two problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sometimes the model gave bad JSON. I added a JSON schema and one example to the prompt. If the JSON is bad, the app tries again one time.&lt;/li&gt;
&lt;li&gt;The model added false facts. For example, it said that a soy candle had coconut wax. I told the model to use only the facts in the notes. I also set the temperature to 0.3. After these changes, the listings used only true facts.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; A hosted API costs money for each listing. A local model costs nothing for each listing. Thus, a one-time price can work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privacy:&lt;/strong&gt; The product data stays on the laptop of the seller.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choice:&lt;/strong&gt; You can change the model with one setting. A user with more memory can use &lt;code&gt;gemma3:4b&lt;/code&gt; for better text.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline:&lt;/strong&gt; The app works with no internet, for example at a craft fair.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A large closed model writes better text. But for short listings, the small open model is sufficient, and it costs nothing to run.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Best Use of Gemma&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>A Hindi garden note for my mom, from Gemma 3 1B on my laptop</title>
      <dc:creator>Harsh Verma</dc:creator>
      <pubDate>Thu, 08 Oct 2026 15:16:29 +0000</pubDate>
      <link>https://dev.to/harshv/a-hindi-garden-note-for-my-mom-from-gemma-3-1b-on-my-laptop-477h</link>
      <guid>https://dev.to/harshv/a-hindi-garden-note-for-my-mom-from-gemma-3-1b-on-my-laptop-477h</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;My mom has a small garden. Each morning she goes out to her plants. She decides what to do from the sky and from what she knows.&lt;/p&gt;

&lt;p&gt;I built a page for her phone. She types the names of her plants one time. Then she pushes one button. The page shows one short task for each plant for this week, in Hindi. Below the tasks, it shows the weather for the week and the vegetables to sow this month.&lt;/p&gt;

&lt;p&gt;The page runs on my laptop. Gemma 3 1B writes the tasks through Ollama. Open-Meteo gives the forecast. Her phone opens the page on our home Wi-Fi.&lt;/p&gt;

&lt;p&gt;She reads the note in less than one minute. Then she puts the phone in her pocket and goes to the plants. The screen is only the start. The work is in the soil, with her hands.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://drive.google.com/file/d/1pg9T_w7n0lCvw9HAfVh4y9vQEjTHag3t/view?usp=sharing" rel="noopener noreferrer"&gt;https://drive.google.com/file/d/1pg9T_w7n0lCvw9HAfVh4y9vQEjTHag3t/view?usp=sharing&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/harshverma27" rel="noopener noreferrer"&gt;
        harshverma27
      &lt;/a&gt; / &lt;a href="https://github.com/harshverma27/touch-grass" rel="noopener noreferrer"&gt;
        touch-grass
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Hacktober Fest '26 -  Weekly Challenge #2
    &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;Garden week&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;My mom keeps a small garden. This is a page she opens on her phone while standing in it. She taps one button and gets a short list of what to do for each of her plants this week, in Hindi.&lt;/p&gt;
&lt;p&gt;It runs on my laptop. Gemma 3 1B through Ollama writes the note, and the weather comes from &lt;a href="https://open-meteo.com" rel="nofollow noopener noreferrer"&gt;Open-Meteo&lt;/a&gt;, which needs no account or key. The page is served over home Wi-Fi, so nothing about her garden goes to anyone else.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it decides&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;The weather facts come from plain rules, not the model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;rain of 5 mm or more in the next two days: skip watering&lt;/li&gt;
&lt;li&gt;38°C or hotter: water early or late, shade the pots&lt;/li&gt;
&lt;li&gt;night at 8°C or colder: no evening watering&lt;/li&gt;
&lt;li&gt;night at 2°C or colder: cover tender plants, frost possible&lt;/li&gt;
&lt;li&gt;what to sow this month, from a fixed table for north…&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/harshverma27/touch-grass" 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 app is one Python file of 147 lines. It has three parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Python rules make the weather facts from the forecast.&lt;/li&gt;
&lt;li&gt;Gemma writes one task for each plant from these facts.&lt;/li&gt;
&lt;li&gt;A filter removes each task that does not agree with the facts.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ul&gt;
&lt;li&gt;The model runs on my laptop. Her plant list and our location stay at home.&lt;/li&gt;
&lt;li&gt;It costs nothing to operate. She can open it each day.&lt;/li&gt;
&lt;li&gt;With no internet, the app continues to work. It uses the last forecast and the local model.&lt;/li&gt;
&lt;li&gt;I could read each raw answer from Gemma and run the model many times. I could also change the chat template and set the seed. The fix for the timeout needed this access to the model.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Best Use of Gemma&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>I built my mom a Hindi spelling fixer that runs on my laptop</title>
      <dc:creator>Harsh Verma</dc:creator>
      <pubDate>Sat, 03 Oct 2026 21:08:20 +0000</pubDate>
      <link>https://dev.to/harshv/i-built-my-mom-a-hindi-spelling-fixer-that-runs-on-my-laptop-4g2j</link>
      <guid>https://dev.to/harshv/i-built-my-mom-a-hindi-spelling-fixer-that-runs-on-my-laptop-4g2j</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;My mom teaches Hindi. She writes her reports, notices and other work in Word, and she types all of it with Gboard's Hindi handwriting and voice input. She does that easily, but later faces problem in correcting mistakes which voice and handwriting input got wrong.&lt;/p&gt;

&lt;p&gt;बच्चों turns into बच्चो. पढ़ाया turns into पढाया. है turns into हे. She then fixes each one by hand, in a Word file she  finds it hard to edit.&lt;/p&gt;

&lt;p&gt;So I built her a small page that runs on my laptop. She uploads a .docx, and she gets back a fixed copy plus a list of every line that changed. Her original file is never touched.&lt;/p&gt;

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

&lt;p&gt;Video: &lt;a href="https://drive.google.com/drive/folders/1gQ7pM90d3quHsdf98rLGVd4XD-wU_3QE" rel="noopener noreferrer"&gt;https://drive.google.com/drive/folders/1gQ7pM90d3quHsdf98rLGVd4XD-wU_3QE&lt;/a&gt;&lt;br&gt;
GitHub Repository: &lt;a href="https://github.com/harshverma27/Hindi-Doc-Fixer" rel="noopener noreferrer"&gt;https://github.com/harshverma27/Hindi-Doc-Fixer&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;आज कक्षा में 'ईदगाह' पाठ पढाया गया। बच्चो ने बहुत ध्यान से सुना।&lt;/td&gt;
&lt;td&gt;आज कक्षा में 'ईदगाह' पाठ पढ़ाया गया। बच्चों ने बहुत ध्यान से सुना।&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;पाठ के कठिन शब्दो का अर्थ बोर्ड पर लिखवाया गया।&lt;/td&gt;
&lt;td&gt;पाठ के कठिन शब्दों का अर्थ बोर्ड पर लिखवाया गया।&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&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;I showed it to her. She said it's good, and that she'll still read through the fixed file out of habit, but it definitely helped. I'll take that. A teacher checking the work is the right outcome.&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/harshverma27" rel="noopener noreferrer"&gt;
        harshverma27
      &lt;/a&gt; / &lt;a href="https://github.com/harshverma27/Hindi-Doc-Fixer" rel="noopener noreferrer"&gt;
        Hindi-Doc-Fixer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Challenge 1 of 5 in our Hacktoberfest DEV Challenges.
    &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;Hindi doc fixer&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;My mom teaches Hindi. She types her Word files with Gboard's Hindi handwriting and voice input, and the text comes out with small spelling and matra mistakes. Fixing them by hand takes her a long time.&lt;/p&gt;
&lt;p&gt;This is a small page on my laptop. She uploads a .docx and gets back a fixed copy. Her original file is not touched.&lt;/p&gt;
&lt;p&gt;It runs Gemma 3 1B through Ollama on the laptop, so her files never leave it.&lt;/p&gt;
&lt;p&gt;Demo video: &lt;a href="https://drive.google.com/drive/folders/1gQ7pM90d3quHsdf98rLGVd4XD-wU_3QE" rel="nofollow noopener noreferrer"&gt;https://drive.google.com/drive/folders/1gQ7pM90d3quHsdf98rLGVd4XD-wU_3QE&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What it fixes&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Only spelling-type mistakes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;short or long matra (ि/ी, ु/ू)&lt;/li&gt;
&lt;li&gt;े/ै and ो/ौ&lt;/li&gt;
&lt;li&gt;missing or extra ं and ँ&lt;/li&gt;
&lt;li&gt;nukta (ढ/ढ़)&lt;/li&gt;
&lt;li&gt;ये/ए (लिये to लिए)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the model changes a word into a different word, drops a word, or touches punctuation, that change is thrown away and her text stays as it was. Spacing, headings and English lines are left alone.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Keeping a line as it&lt;/h2&gt;…&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/harshverma27/Hindi-Doc-Fixer" 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 thing is one Python file of about 120 lines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 3 1B&lt;/strong&gt; running locally through &lt;strong&gt;Ollama&lt;/strong&gt; does the fixing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;python-docx&lt;/strong&gt; reads the Word file paragraph by paragraph and writes the fixed copy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gradio&lt;/strong&gt; gives her an upload button and a download button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fun part was not getting the model to fix things. It was stopping it from fixing things it shouldn't :)&lt;/p&gt;

&lt;p&gt;A 1B model is small, and on Hindi it showed. The first run swapped है for हूँ, which changed the sentence. It replaced बच्चो with छात्रों, a different word. It dropped "1." from numbered questions, squashed her spacing, removed quotes and added commas. On a test paper it even "fixed" a sentence that was wrong on purpose, because the question asked students to correct it.&lt;/p&gt;

&lt;p&gt;So I stopped trusting the model's output as a whole and started checking it word by word. The rule I ended up with is simple. A change is accepted only if the old word and the new word are the same once you ignore the things voice typing gets wrong:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;short or long matra (ि/ी, ु/ू)&lt;/li&gt;
&lt;li&gt;े/ै and ो/ौ&lt;/li&gt;
&lt;li&gt;ं and ँ&lt;/li&gt;
&lt;li&gt;nukta (ढ/ढ़)&lt;/li&gt;
&lt;li&gt;ये/ए&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the model changes a consonant, adds or drops a word, or touches punctuation, that change is thrown away and her text stays. The fixed words are put back in place, so spacing and layout don't move.&lt;/p&gt;

&lt;p&gt;This blocks good edits sometimes. It won't turn लिखिये into लिखें, because that's style, not spelling. It misses some real mistakes too. For a teacher's document, missing a typo is much better than changing entirely.&lt;/p&gt;

&lt;p&gt;For the sentences that are wrong on purpose, she starts the line with &lt;code&gt;#&lt;/code&gt;. The app skips that line and removes the &lt;code&gt;#&lt;/code&gt; in the fixed copy.&lt;/p&gt;

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

&lt;p&gt;Her files are about her students. Names, attendance, who is struggling with what. I didn't want any of that going to someone else's server, and with an open model on the laptop it doesn't. It also works without internet and costs nothing to run, which matters for a tool she'll use every day.&lt;/p&gt;

&lt;p&gt;Being open also changed how I built it. I could run the model as many times as I wanted, see exactly what it did to each sentence, and build the guard around its actual mistakes. And since it's just Ollama, swapping in a bigger Gemma later is a one-line change.&lt;/p&gt;

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

&lt;p&gt;Best Use of Gemma&lt;/p&gt;

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