<?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: Madhav Gupta</title>
    <description>The latest articles on DEV Community by Madhav Gupta (@madhav_gupta_7caf016167d2).</description>
    <link>https://dev.to/madhav_gupta_7caf016167d2</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%2F3692952%2F2b495873-7222-4e32-9090-dae2fcb74fc9.jpg</url>
      <title>DEV Community: Madhav Gupta</title>
      <link>https://dev.to/madhav_gupta_7caf016167d2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/madhav_gupta_7caf016167d2"/>
    <language>en</language>
    <item>
      <title>Trailside: an open-weight bird call identifier that talks back</title>
      <dc:creator>Madhav Gupta</dc:creator>
      <pubDate>Fri, 09 Oct 2026 08:59:28 +0000</pubDate>
      <link>https://dev.to/madhav_gupta_7caf016167d2/trailside-an-open-weight-bird-call-identifier-that-talks-back-21eb</link>
      <guid>https://dev.to/madhav_gupta_7caf016167d2/trailside-an-open-weight-bird-call-identifier-that-talks-back-21eb</guid>
      <description>&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Trailside&lt;/strong&gt; is a bird call identifier built to get you outside — and keep you outside. Open the PWA, tap record, stand still for 5–20 seconds, and it tells you what you heard &lt;strong&gt;out loud&lt;/strong&gt;: the species, the confidence, and a short spoken field note. No account, no app-store install, no staring at a screen mid-trudge.&lt;/p&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%2Fo18tomk0afzuugk3o9zl.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%2Fo18tomk0afzuugk3o9zl.png" alt=" " width="520" height="920"&gt;&lt;/a&gt;&lt;br&gt;
It's for day hikers, beginner birders, parents with curious kids, and anyone who walks past birds they'd like to &lt;em&gt;name&lt;/em&gt; without stopping to fiddle with a phone.&lt;/p&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%2Fujxj8gorj93wasmn7r3e.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%2Fujxj8gorj93wasmn7r3e.png" alt=" " width="520" height="920"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Try it live: &lt;strong&gt;&lt;a href="https://trailside-0hlr.onrender.com" rel="noopener noreferrer"&gt;https://trailside-0hlr.onrender.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Verified end-to-end from the deploy: a 34-second American Robin recording returned &lt;strong&gt;American Robin @ 90%&lt;/strong&gt; (plus Song Sparrow and House Finch hints) with an ElevenLabs-narrated field note in ~15 seconds.&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;Open source: &lt;strong&gt;&lt;a href="https://github.com/madhavgupta07/trailside" rel="noopener noreferrer"&gt;https://github.com/madhavgupta07/trailside&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python/FastAPI backend, plain-JS dependency-free PWA frontend (no build step)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onnxruntime&lt;/code&gt; CPU inference — no TensorFlow, no GPU needed&lt;/li&gt;
&lt;li&gt;Async job flow so a 30-second clip never trips a slow gateway timeout&lt;/li&gt;
&lt;li&gt;10 unit/integration tests, including a real-audio classification test (&lt;code&gt;american_robin.mp3&lt;/code&gt; → American Robin @ 90.1% locally)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;The whole experience is built &lt;em&gt;around&lt;/em&gt; open-weight AI — the species engine is the core, and the narrator is a second open-weight model on top:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Piece&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;License&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;BirdNET v3.0&lt;/strong&gt; (Cornell / TU Chemnitz, via &lt;code&gt;tphakala/BirdNET-v3.0-Models&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;11,560-species bioacoustics classifier; I use the 800-class &lt;code&gt;north-america-east&lt;/code&gt; regional ONNX slice (~150 MB)&lt;/td&gt;
&lt;td&gt;CC BY-SA 4.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Gemma 4&lt;/strong&gt; (Google)&lt;/td&gt;
&lt;td&gt;writes the 2–3 sentence spoken field note; served via an OpenAI-compatible endpoint (OpenRouter, free &lt;code&gt;google/gemma-4-26b-a4b-it:free&lt;/code&gt; by default)&lt;/td&gt;
&lt;td&gt;Gemma Terms (open weights)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ElevenLabs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;narrates the note back so the result is &lt;em&gt;heard&lt;/em&gt;, not read&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Render&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Blueprint (&lt;code&gt;render.yaml&lt;/code&gt;) deploys FastAPI; &lt;code&gt;startCommand&lt;/code&gt; downloads and checksum-verifies the model at boot&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Pipeline: &lt;code&gt;mic → browser WAV encode (16-bit PCM) → FastAPI → BirdNET (32 kHz, 5 s windows, running max-aggregate) → top-5 species → Gemma field note → ElevenLabs MP3, played back in the page&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Resilience was a real constraint, not a checkbox: the free Gemma endpoint rate-limits hard under load, so narration retries with backoff and then degrades to a deterministic offline template note — the app &lt;strong&gt;never errors&lt;/strong&gt; because a model is busy. There's the same graceful no-voice fallback if no TTS key is set. The API surfaces &lt;em&gt;why&lt;/em&gt; (&lt;code&gt;note_error&lt;/code&gt;) instead of hiding it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Trail use is exactly where closed APIs fail:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It can work fully offline.&lt;/strong&gt; The identical code path runs on a laptop with llama.cpp and no internet at all. A network drop mid-hike doesn't produce an error — it produces a gentler fallback note.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your recordings stay yours.&lt;/strong&gt; Audio goes to a server you own; you can run it yourself and take the network out entirely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swap anything at runtime.&lt;/strong&gt; Regional model, Gemma size, voice, provider — all env vars, zero rewrites. Fine-tune a model and point a variable at it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It costs nothing at the core.&lt;/strong&gt; Both core models are free weights; BirdNET inference is pure CPU on the cheapest deploy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A closed API literally cannot offer a free, server-owned model that keeps working when the phone loses signal in the woods. That's the difference open weights made here.&lt;/p&gt;
&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;p&gt;The full build transcript, as it happened:&lt;/p&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;Session 2026-10-09 08:14&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;Take a Touch Grass / open-source AI idea and build it: a bird call identifier that gets people outside, with open-weight models at its core, deployable on Render's free plan.&lt;/p&gt;

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

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Architecture: ref — browser mic -&amp;gt; client-side WAV encode (no ffmpeg) -&amp;gt; FastAPI -&amp;gt; BirdNET v3.0 ONNX (open weights, regional north-america-east, 800 classes) -&amp;gt; Gemma writes a spoken field note via OpenRouter -&amp;gt; ElevenLabs TTS. Scaffolding FastAPI app, classifier service, config, requirements.&lt;/p&gt;

                &lt;/div&gt;
              &lt;div class="agent-session-tool-call"&gt;
                
                  &lt;span class="agent-session-chevron"&gt;▸&lt;/span&gt;
                  &lt;span class="tool-name tool-name-writefile"&gt;write_file&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;app/services/classifier.py (BirdNET ONNX loading: scipy resample_poly to 32kH...&lt;/span&gt;
                
                &lt;div class="agent-session-tool-detail"&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Input&lt;/div&gt;
                      &lt;pre class="agent-session-pre highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;classifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;py &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BirdNET&lt;/span&gt; &lt;span class="n"&gt;ONNX&lt;/span&gt; &lt;span class="n"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scipy&lt;/span&gt; &lt;span class="n"&gt;resample_poly&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="n"&gt;kHz&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;windowing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uncontrollable&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;SessionOptions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Output&lt;/div&gt;
                      &lt;pre class="agent-session-pre highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Classifier&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="n"&gt;written&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="n"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;download&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt; &lt;span class="n"&gt;verify&lt;/span&gt; &lt;span class="n"&gt;script&lt;/span&gt; &lt;span class="n"&gt;added&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&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;Add tests and a real audio fixture, then download the model and verify classification locally.&lt;/p&gt;

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

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Downloaded the 149MB regional model, grabbed an American Robin recording from Wikimedia Commons as a fixture, wired narrator (Gemma) + TTS (ElevenLabs) with graceful fallbacks, and wrote API + service tests with mocked HTTP.&lt;/p&gt;

                &lt;/div&gt;
              &lt;div class="agent-session-tool-call"&gt;
                
                  &lt;span class="agent-session-chevron"&gt;▸&lt;/span&gt;
                  &lt;span class="tool-name tool-name-bash"&gt;bash&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;python -m pytest tests/ -q&lt;/span&gt;
                
                &lt;div class="agent-session-tool-detail"&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Input&lt;/div&gt;
                      &lt;pre class="agent-session-pre agent-session-terminal"&gt;&lt;code&gt;$ python -m pytest tests/ -q&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Output&lt;/div&gt;
                      &lt;pre class="agent-session-pre"&gt;&lt;code&gt;10 passed — classifier returns American Robin @ 90.1% on the 34s fixture&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Deployed via render.yaml Blueprint; set OpenRouter + ElevenLabs keys in Render env; health endpoint reports model/gemma/elevenlabs readiness.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&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;Gemma narration is silently falling back to the offline template on production. Find out why.&lt;/p&gt;

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

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
              &lt;div class="agent-session-tool-call"&gt;
                
                  &lt;span class="agent-session-chevron"&gt;▸&lt;/span&gt;
                  &lt;span class="tool-name tool-name-bash"&gt;bash&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;curl /api/identify with american_robin.mp3; inspect note_error&lt;/span&gt;
                
                &lt;div class="agent-session-tool-detail"&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Input&lt;/div&gt;
                      &lt;pre class="agent-session-pre agent-session-terminal"&gt;&lt;code&gt;$ curl /api/identify with american_robin.mp3; inspect note_error&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Output&lt;/div&gt;
                      &lt;pre class="agent-session-pre"&gt;&lt;code&gt;note_error: 404 'No endpoints found for google/gemma-3n-e4b-it:free' — OpenRouter no longer serves gemma-3n&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Swapped to google/gemma-4-26b-a4b-it:free (open-weight Gemma 4, actually serviced), updated docs and the DEV post, redeployed. Next prod run hit 429 rate limits — added 3 retries with backoff before the template fallback.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&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;Long clips time out / 502 on the 512MB free instance. Make the API fit the free tier.&lt;/p&gt;

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

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Diagnosed peak-memory &amp;amp; long-request issues: inference now runs windows one-at-a-time (batches stayed safe), threads=1, analysis windows capped; then made /api/identify fully async — POST returns a job_id in ~0ms and the page polls GET /api/jobs/{id}.&lt;/p&gt;

                &lt;/div&gt;
              &lt;div class="agent-session-tool-call"&gt;
                
                  &lt;span class="agent-session-chevron"&gt;▸&lt;/span&gt;
                  &lt;span class="tool-name tool-name-editfile"&gt;edit_file&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;app/jobs.py (ThreadPoolExecutor job store) + frontend app.js polling loop&lt;/span&gt;
                
                &lt;div class="agent-session-tool-detail"&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Input&lt;/div&gt;
                      &lt;pre class="agent-session-pre highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;py &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ThreadPoolExecutor&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;frontend&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;js&lt;/span&gt; &lt;span class="n"&gt;polling&lt;/span&gt; &lt;span class="n"&gt;loop&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Output&lt;/div&gt;
                      &lt;pre class="agent-session-pre highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Verified&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;prod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;clip&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;American&lt;/span&gt; &lt;span class="n"&gt;Robin&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;ElevenLabs&lt;/span&gt; &lt;span class="n"&gt;narration&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="mi"&gt;502&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&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;Wrap up the submission: structure the DEV post per the challenge template, fill verified facts, and prep the agent session embed.&lt;/p&gt;

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

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Wrote DEV_SUBMISSION.md matching the official template (What I Built / Demo / Code / How I Built It / Why Open Innovation / My Agent Session / Prize Categories), filled in the live URL and verified results, and saved this session transcript for the {% agent_session %} embed.&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;
        10 of 10 messages
    &lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;(If the embed doesn't render on your view, the direct link is &lt;a href="https://dev.to/agent_sessions/session-2026-10-09-0814-tf0pln"&gt;https://dev.to/agent_sessions/session-2026-10-09-0814-tf0pln&lt;/a&gt;)&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Best Use of Gemma (open-weight Gemma 4 writing the field note)&lt;/li&gt;
&lt;li&gt;Best Use of ElevenLabs (spoken narration keeps your eyes on the trees)&lt;/li&gt;
&lt;li&gt;Deploy/Run on Render (Blueprint deploy; the model is downloaded + checksummed at boot)&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Built for Round 1 of the Hacktoberfest 2026 "Touch Grass" challenge. Open weights for the win — now go outside and listen.&lt;/em&gt;&lt;/p&gt;

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