<?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: Radhika Godambe</title>
    <description>The latest articles on DEV Community by Radhika Godambe (@radhikaaa25).</description>
    <link>https://dev.to/radhikaaa25</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%2F2185750%2F303dd346-a17c-4480-8443-7947b40af2be.png</url>
      <title>DEV Community: Radhika Godambe</title>
      <link>https://dev.to/radhikaaa25</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/radhikaaa25"/>
    <language>en</language>
    <item>
      <title>THE VEIL — I Built an AI Ouija Board That Runs Entirely on Your Machine 🕯️</title>
      <dc:creator>Radhika Godambe</dc:creator>
      <pubDate>Sat, 31 Oct 2026 15:39:00 +0000</pubDate>
      <link>https://dev.to/radhikaaa25/the-veil-i-built-an-ai-ouija-board-that-runs-entirely-on-your-machine-5fof</link>
      <guid>https://dev.to/radhikaaa25/the-veil-i-built-an-ai-ouija-board-that-runs-entirely-on-your-machine-5fof</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week4-2026-10-26"&gt;Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;THE VEIL&lt;/strong&gt; is an AI-powered Ouija board that runs entirely on your local machine — no cloud, no API keys, no internet required once you've pulled the model.&lt;/p&gt;

&lt;p&gt;You ask a question, and an ancient spirit answers. But not like a chatbot. The planchette physically glides across the board, pausing over each letter, illuminating it, and spelling out a cryptic response one character at a time. When the message is complete, it drifts to GOODBYE.&lt;/p&gt;

&lt;p&gt;The theme said &lt;em&gt;Ghost in the Machine&lt;/em&gt;. I took it literally: there's an LLM living inside Ollama on your laptop, pretending to be a spirit trapped behind a 19th-century parlor game. It doesn't know it's software. It speaks in fragments. It never explains itself.&lt;/p&gt;

&lt;p&gt;The inspiration was simple. It's October 31st. What if a séance actually worked — and the spirit on the other side was a 3-billion-parameter language model running on localhost?&lt;/p&gt;

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

&lt;p&gt;The experience flows like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Landing&lt;/strong&gt; — A dark screen. "THE VEIL" in gold gothic lettering. Floating particles. &lt;em&gt;Some questions are better left unanswered.&lt;/em&gt; Click ENTER THE SÉANCE.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Board&lt;/strong&gt; — A full CSS/SVG Ouija board fills the screen: curved alphabet rows (A–M, N–Z), numbers 0–9, YES and NO in the corners, GOODBYE at the bottom. Flickering candles at the edges. A film grain overlay. A wooden planchette with a circular viewing window hovers at center.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ask&lt;/strong&gt; — Type your question. Click SUMMON. The screen dims. The planchette trembles. &lt;em&gt;Reaching beyond the veil...&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Response&lt;/strong&gt; — The planchette begins to move. It glides to the first letter — the letter glows gold — the character appears in the transcript below. Then the next. And the next. Each movement is spring-animated using actual DOM coordinates, so it's pixel-accurate at any screen size.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Goodbye&lt;/strong&gt; — When the message is complete, the planchette drifts to GOODBYE. You can ask again or end the séance.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The whole thing runs at &lt;code&gt;localhost:5173&lt;/code&gt; (frontend) and &lt;code&gt;localhost:8000&lt;/code&gt; (backend).&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://github.com/radhikaaa25/the-veil
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h3&gt;
  
  
  The Stack
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;React + Vite&lt;/td&gt;
&lt;td&gt;Fast dev, hot reload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Styling&lt;/td&gt;
&lt;td&gt;Tailwind CSS v4 + vanilla CSS&lt;/td&gt;
&lt;td&gt;Design tokens via &lt;code&gt;@theme&lt;/code&gt;, plus detailed component styles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Animation&lt;/td&gt;
&lt;td&gt;Framer Motion&lt;/td&gt;
&lt;td&gt;Spring physics for the planchette, &lt;code&gt;useMotionValue&lt;/code&gt; + &lt;code&gt;useSpring&lt;/code&gt; for natural gliding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Python + FastAPI&lt;/td&gt;
&lt;td&gt;Thin bridge between frontend and Ollama&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI&lt;/td&gt;
&lt;td&gt;Ollama + &lt;code&gt;llama3.2:3b&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Fully local, open-weight, no API key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audio&lt;/td&gt;
&lt;td&gt;Web Audio API&lt;/td&gt;
&lt;td&gt;Ambient drone generated from oscillators — no external sound files&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The Open-Source AI
&lt;/h3&gt;

&lt;p&gt;The AI is &lt;strong&gt;Ollama&lt;/strong&gt; running &lt;strong&gt;llama3.2:3b&lt;/strong&gt; (Meta's open-weight model, 3 billion parameters). The backend sends each question to Ollama's chat API with this system prompt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You are an ancient, mysterious spirit communicating through a Ouija board. Respond with a short, eerie, poetic, and cryptic message. Keep responses under 15 words. Never explain yourself. Avoid modern slang, emojis, or references to being an AI.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The model stays in character remarkably well at this size. Short, constrained prompts are where small open-weight models shine — you don't need GPT-4 to say "THE ANSWER LIES BENEATH WHAT YOU HAVE FORGOTTEN" in a creepy voice.&lt;/p&gt;

&lt;p&gt;The response is sanitized server-side: stripped to uppercase, punctuation removed, collapsed to only characters that exist on the board (A–Z, 0–9, spaces). The frontend never has to guess whether a character is renderable.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Planchette Animation
&lt;/h3&gt;

&lt;p&gt;This was the hardest and most important part. The planchette doesn't use a typing effect. It physically moves.&lt;/p&gt;

&lt;p&gt;Every letter on the board is a React ref. When the AI response arrives, the app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Splits the response into individual characters&lt;/li&gt;
&lt;li&gt;For each character, calls &lt;code&gt;getBoundingClientRect()&lt;/code&gt; on that letter's DOM element&lt;/li&gt;
&lt;li&gt;Calculates the position relative to the board container&lt;/li&gt;
&lt;li&gt;Sets a Framer Motion spring target (&lt;code&gt;stiffness: 80, damping: 22, mass: 0.8&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The planchette glides to the letter with natural deceleration&lt;/li&gt;
&lt;li&gt;The letter illuminates with a gold glow&lt;/li&gt;
&lt;li&gt;The character appends to the revealed text below the board&lt;/li&gt;
&lt;li&gt;After all characters: the planchette moves to GOODBYE&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because positions are read from the DOM at animation time, the board is fully responsive. Resize the window and the planchette still lands exactly on each letter.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Atmosphere
&lt;/h3&gt;

&lt;p&gt;The board itself is pure CSS — layered gradients that simulate dark wood grain, a double border for the antique frame effect, and an inner box-shadow for depth. Typography uses Cinzel Decorative (for titles) and IM Fell English (for body text), both loaded from Google Fonts.&lt;/p&gt;

&lt;p&gt;The particles are a &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; element with 40 floating golden dots that drift upward and fade. The candles are CSS animations (&lt;code&gt;@keyframes flicker&lt;/code&gt;) with a radial gradient glow. The ambient sound is generated entirely from the Web Audio API — three sine-wave oscillators (55Hz, 220Hz, 36.7Hz) with LFO modulation for a slow, eerie drone. No audio files ship with the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;React (Vite :5173)
  ↓ POST /api/ask {question}
FastAPI (:8000)
  ↓ Ollama chat API
llama3.2:3b (localhost:11434)
  ↓ response
FastAPI → sanitize → {answer}
  ↓
React → split chars → animate planchette → reveal text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend is 2 files. The frontend is 9 components. No database, no auth, no cloud.&lt;/p&gt;

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

&lt;p&gt;This project only works because the AI is open and local.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It works with the lights off.&lt;/strong&gt; Once you've pulled &lt;code&gt;llama3.2:3b&lt;/code&gt; from Ollama, the entire séance runs without internet. The model sits on your disk. The backend talks to localhost. The frontend talks to the backend. No tokens, no rate limits, no "service unavailable."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The persona stays in character.&lt;/strong&gt; With a closed API, you're fighting content filters. "You are a spirit communicating through a Ouija board" is exactly the kind of prompt that triggers safety guardrails on commercial models. A local open-weight model doesn't second-guess the fiction. It plays the role.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It costs nothing to run.&lt;/strong&gt; A 3B parameter model runs comfortably on a laptop CPU. No GPU required. No billing page. No surprise invoice because your Halloween party guests asked it 200 questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's private.&lt;/strong&gt; Your questions to the spirit board stay on your machine. Nobody's logging "will I find love" or "is someone watching me" to a server in Virginia.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The model is swappable.&lt;/strong&gt; Don't like the responses? Change &lt;code&gt;OLLAMA_MODEL&lt;/code&gt; in &lt;code&gt;.env&lt;/code&gt; to &lt;code&gt;mistral&lt;/code&gt;, &lt;code&gt;phi3&lt;/code&gt;, &lt;code&gt;gemma2&lt;/code&gt;, or any model Ollama supports. The prompt engineering is simple enough that most models handle it well.&lt;/p&gt;

&lt;p&gt;A closed API could technically generate the text. But it couldn't do it offline, for free, without filters, on a Halloween night with the Wi-Fi turned off for atmosphere. Open made this the experience it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Spirit of It
&lt;/h2&gt;

&lt;p&gt;I built this on Halloween. That wasn't an accident.&lt;/p&gt;

&lt;p&gt;There's something about a Ouija board that a chatbot window can never replicate — the tension of watching the planchette move, letter by letter, not knowing where it's going. The pause between characters. The moment you realize the word it's spelling.&lt;/p&gt;

&lt;p&gt;When I first got the planchette animation working and asked it "Is someone watching me?", it spelled out:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;THE SHADOWS REMEMBER YOUR NAME&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I was alone in my room at midnight. The candles were flickering on screen. The ambient drone was humming through my headphones. And for about three seconds, I forgot it was a language model.&lt;/p&gt;

&lt;p&gt;That's the moment this project is for.&lt;/p&gt;

</description>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>ScopeGuard: Privacy-First Open-Source AI Scope Creep Detector for Freelancers</title>
      <dc:creator>Radhika Godambe</dc:creator>
      <pubDate>Sun, 18 Oct 2026 18:58:35 +0000</pubDate>
      <link>https://dev.to/radhikaaa25/scopeguard-privacy-first-open-source-ai-scope-creep-detector-for-freelancers-1flh</link>
      <guid>https://dev.to/radhikaaa25/scopeguard-privacy-first-open-source-ai-scope-creep-detector-for-freelancers-1flh</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;Every freelance developer knows the dread of this Slack message:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Hey! The site looks great. Quick question—can we also add user authentication, a customer admin portal, and Stripe checkout before we go live on Friday?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Freelancers call it &lt;strong&gt;scope creep&lt;/strong&gt;. In reality, it is unbilled hours, blown deadlines, and unpaid overtime. According to freelancer surveys, over 70% of independent contractors absorb unbilled client work simply because pushing back feels confrontational or risks the client relationship. &lt;/p&gt;

&lt;p&gt;Even worse: freelancers work under strict &lt;strong&gt;NDAs and confidentiality agreements&lt;/strong&gt;. You cannot simply upload your client’s proprietary statement of work (SOW) or confidential emails into ChatGPT or closed cloud APIs without violating client trust and contract terms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introducing ScopeGuard 🛡️
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Protect your time. Get paid for every extra mile.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;ScopeGuard&lt;/strong&gt; is a 100% local, privacy-first AI application that acts as an objective contractual shield. It automatically analyzes incoming client messages against original signed agreements, flags scope creep with exact clause citations, drafts boundary-enforcing replies in multiple tones, and turns unpaid requests into billable &lt;strong&gt;Change Order Quotations&lt;/strong&gt; with 1-click PDF exports.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who Would Pay For It?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Freelance Web &amp;amp; Mobile Developers:&lt;/strong&gt; Who lose an average of $2,000–$8,000 annually in unbilled "small favors".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design &amp;amp; Digital Agencies:&lt;/strong&gt; Managing multiple simultaneous client contracts who need objective change-order enforcement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Independent Consultants &amp;amp; Contractors:&lt;/strong&gt; Who want an objective, neutral third party to draft polite, contract-backed pushback.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If ScopeGuard captures just &lt;strong&gt;one&lt;/strong&gt; extra change order for $750, a $15/month subscription pays for itself for 4 years on day one.&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/radhikaaa25" rel="noopener noreferrer"&gt;
        radhikaaa25
      &lt;/a&gt; / &lt;a href="https://github.com/radhikaaa25/ScopeGuard" rel="noopener noreferrer"&gt;
        ScopeGuard
      &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;ScopeGuard 🛡️&lt;/h1&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Protect your time. Get paid for every extra mile.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ScopeGuard is an open-source, privacy-first AI application designed specifically for freelancers, agencies, and independent contractors to detect and prevent &lt;strong&gt;scope creep&lt;/strong&gt;. By automatically comparing incoming client requests against signed project agreements and statement-of-work (SOW) documents, ScopeGuard identifies out-of-scope work, generates boundary-enforcing client replies in multiple tones, and builds deterministic change-order quotations with instant PDF exports.&lt;/p&gt;
&lt;p&gt;Developed for the &lt;strong&gt;Hacktoberfest Open-Source AI Challenge&lt;/strong&gt; under the theme &lt;strong&gt;Side Hustle&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;💡 The Problem &amp;amp; The Solution&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Problem:&lt;/strong&gt; Freelancers frequently agree to fixed-scope projects, only for clients to request "small tweaks" and extra features disguised as minor additions (e.g., authentication, dark mode, blog CMS, payment gateways). Over time, this leads to unbilled hours, delayed delivery, and client tension.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Solution:&lt;/strong&gt; ScopeGuard acts as an objective, contractual shield. It extracts clauses from your agreements, semantically compares incoming messages against agreed deliverables…&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/radhikaaa25/ScopeGuard" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;em&gt;Repository:&lt;/em&gt; &lt;a href="https://github.com/radhikaaa25/ScopeGuard" rel="noopener noreferrer"&gt;https://github.com/radhikaaa25/ScopeGuard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ScopeGuard is built as a complete, production-grade application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; Python 3.11+ / Django 5 with Django REST Framework&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; React 19, TypeScript, Vite, Tailwind CSS (sleek dark mode design system), and Recharts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDF Engine:&lt;/strong&gt; Deterministic ReportLab document generation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License:&lt;/strong&gt; Open-source under MIT&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;ScopeGuard was engineered from scratch around a &lt;strong&gt;local-first open-source AI pipeline&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌────────────────────────────────────────────────────────────────────────┐
│                        SCOPEGUARD ARCHITECTURE                         │
└────────────────────────────────────────────────────────────────────────┘

 ┌──────────────────────────────────────────────────────────────────────┐
 │                  MODERN REACT FRONTEND (PORT 5173)                   │
 │  ┌────────────────────┐  ┌─────────────────────┐  ┌───────────────┐  │
 │  │ Vite + React 19    │  │ Tailwind Dark Theme │  │ React Router  │  │
 │  └────────────────────┘  └─────────────────────┘  └───────────────┘  │
 │  ┌────────────────────┐  ┌─────────────────────┐  ┌───────────────┐  │
 │  │ Recharts Analytics │  │ Lucide UI Icons     │  │ Axios Client  │  │
 │  └────────────────────┘  └─────────────────────┘  └───────────────┘  │
 └──────────────────────────────────┬───────────────────────────────────┘
                                    │ HTTP / REST API (Port 8000)
                                    ▼
 ┌──────────────────────────────────────────────────────────────────────┐
 │                     DJANGO REST FRAMEWORK BACKEND                    │
 │  ┌────────────────────────────────────────────────────────────────┐  │
 │  │ Endpoints: /api/projects  /agreements  /analyses  /quotations   │  │
 │  └────────────────────────────────┬───────────────────────────────┘  │
 │          ┌────────────────────────┼────────────────────────┐         │
 │          ▼                        ▼                        ▼         │
 │  ┌───────────────┐        ┌────────────────┐       ┌───────────────┐ │
 │  │ SQLite / ORM  │        │ ReportLab PDF  │       │ Document Text │ │
 │  │ Database      │        │ Change Orders  │       │ PDF, DOCX, TXT│ │
 │  └───────────────┘        └────────────────┘       └───────────────┘ │
 └──────────────────────────────────┬───────────────────────────────────┘
                                    │ Local Pipeline (Zero Cloud APIs)
                                    ▼
 ┌──────────────────────────────────────────────────────────────────────┐
 │                    LOCAL OPEN-SOURCE AI PIPELINE                     │
 │  ┌────────────────────────┐          ┌────────────────────────────┐  │
 │  │ ChromaDB Vector Store  │          │ SentenceTransformers       │  │
 │  │ (Local HNSW Index)     │◄────────►│ (all-MiniLM-L6-v2)         │  │
 │  └───────────┬────────────┘          └──────────────┬─────────────┘  │
 │              │                                      │                │
 │              ▼                                      ▼                │
 │  ┌────────────────────────┐          ┌────────────────────────────┐  │
 │  │ Ollama Local LLM       │          │ Local Semantic Fallback    │  │
 │  │ (llama3 / qwen3)       │◄────────►│ (Deterministic Regex/NLP)  │  │
 │  └────────────────────────┘          └────────────────────────────┘  │
 └──────────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Open AI Components
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Local LLM Inference via Ollama:&lt;/strong&gt; All deep reasoning and contractual extraction runs locally through &lt;strong&gt;Ollama&lt;/strong&gt; using open-weight models such as &lt;code&gt;llama3:8b&lt;/code&gt;, &lt;code&gt;qwen3:8b&lt;/code&gt;, or &lt;code&gt;gemma2:9b&lt;/code&gt;. No requests leave your computer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local Vector Search with ChromaDB:&lt;/strong&gt; When an agreement (PDF, DOCX, or TXT) is uploaded, it is chunked and indexed into an on-device &lt;strong&gt;ChromaDB&lt;/strong&gt; vector database with cosine similarity search.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local Embeddings with SentenceTransformers:&lt;/strong&gt; Semantic chunking uses &lt;code&gt;all-MiniLM-L6-v2&lt;/code&gt; locally via PyTorch—delivering millisecond semantic retrieval with zero cloud dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resilient Local NLP Fallback Engine:&lt;/strong&gt; If a freelancer is running on battery or Ollama is offline, ScopeGuard automatically falls back to an internal deterministic regex and semantic rule engine. The app &lt;strong&gt;never crashes&lt;/strong&gt; and remains 100% functional offline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic Pricing Engine:&lt;/strong&gt; Financial calculations (hourly rates, line items, and totals) are strictly deterministic math—preventing LLM hallucination on financial agreements.&lt;/li&gt;
&lt;/ol&gt;




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

&lt;p&gt;Open innovation is not just an implementation detail for ScopeGuard—&lt;strong&gt;it is the entire reason the product can exist.&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Client Confidentiality &amp;amp; NDA Compliance:&lt;/strong&gt; Freelancers cannot paste client agreements, trade secrets, or unreleased feature roadmaps into OpenAI or cloud LLM endpoints. Closed APIs introduce data leakage risks and terms-of-service surveillance. Open-weight models running on-device guarantee 100% data privacy and NDA compliance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero Marginal Inference Cost:&lt;/strong&gt; For a side hustle or bootstrapped solo product, closed API rate limits and token fees eat margins alive. By leveraging open-weight models, ScopeGuard runs with $0 in recurring inference costs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Vendor Lock-In or Arbitrary De-platforming:&lt;/strong&gt; Closed AI providers frequently deprecate model endpoints, alter alignment rules, or raise prices without notice. Open-weight models provide perpetual reproducibility and reliability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Targeted Semantic Precision:&lt;/strong&gt; By combining local vector search with open embeddings, we achieve high-precision clause retrieval without paying to feed entire 50-page contracts into huge cloud context windows.&lt;/li&gt;
&lt;/ol&gt;




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

&lt;p&gt;ScopeGuard was pair-programmed using DevRelay and the Antigravity agentic workflow to scaffold the Django REST architecture, build the local ChromaDB pipeline, and implement the React 19 UI system.&lt;/p&gt;




&lt;h2&gt;
  
  
  My First User
&lt;/h2&gt;

&lt;p&gt;To test ScopeGuard in the real world, I put it into the hands of my friend &lt;strong&gt;Sarah&lt;/strong&gt;, a freelance frontend developer who builds custom Next.js web applications for local businesses.&lt;/p&gt;

&lt;p&gt;She was in the middle of a project where the client sent this exact message:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Could you also set up a members-only portal so our customers can create accounts, log in, and view their past orders?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We uploaded her original project agreement into ScopeGuard and ran the client's message through the analyzer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Result:&lt;/strong&gt; ScopeGuard flagged the request as &lt;code&gt;OUT_OF_SCOPE&lt;/code&gt; with 92% confidence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cited Clause:&lt;/strong&gt; &lt;code&gt;EXCLUDED FROM SCOPE: User authentication, customer login systems, or backend databases.&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action:&lt;/strong&gt; ScopeGuard generated a &lt;strong&gt;Professional&lt;/strong&gt; reply acknowledging the idea, explaining that it falls outside the initial milestone, and generated a &lt;strong&gt;$1,350 Change Order Quotation&lt;/strong&gt; (18 hours @ $75/hr).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sarah sent the response directly to the client. Within two hours, the client replied: &lt;em&gt;"Understood! Let's approve the change order so we can get it into the next phase."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Her feedback:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"The hardest part of freelancing is telling a client 'no' without sounding difficult. ScopeGuard made it completely objective—it wasn't me saying no, it was the contract we both signed. I would easily pay $20 a month for this peace of mind."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




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

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hacktoberfest Open-Source AI Challenge: Week 2 — Side Hustle (Main Track)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma (Open-Weight Model Category):&lt;/strong&gt; Tested and fully compatible with &lt;code&gt;gemma2:9b&lt;/code&gt; and &lt;code&gt;gemma2:2b&lt;/code&gt; on Ollama for efficient on-device contractual inference.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Protect your time. Get paid for every extra mile. Check out the open-source repo on &lt;a href="https://github.com/radhikaaa25/ScopeGuard" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and star the project!&lt;/em&gt; 🛡️&lt;/p&gt;

</description>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>ai</category>
      <category>freelance</category>
    </item>
    <item>
      <title>Touch Grass: Natural Language Outdoor Discovery</title>
      <dc:creator>Radhika Godambe</dc:creator>
      <pubDate>Sun, 11 Oct 2026 19:57:21 +0000</pubDate>
      <link>https://dev.to/radhikaaa25/touch-grass-natural-language-outdoor-discovery-101h</link>
      <guid>https://dev.to/radhikaaa25/touch-grass-natural-language-outdoor-discovery-101h</guid>
      <description>&lt;p&gt;&lt;em&gt;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;Finding somewhere to go outdoors shouldn't require browsing through multiple websites, filtering endless map results, or scrolling through hiking forums.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Touch Grass&lt;/strong&gt; is an open-source, AI-powered outdoor discovery application that lets users search for trails, parks, and running clubs using natural language.&lt;/p&gt;

&lt;p&gt;Instead of navigating multiple filters, users can simply ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Show me easy shaded trails under 3 miles."&lt;/li&gt;
&lt;li&gt;"Which parks in Austin have restrooms and allow dogs?"&lt;/li&gt;
&lt;li&gt;"Find me a weekend run club that runs less than 5 miles."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The application uses an LLM-powered Text-to-SQL agent to translate these questions into SQLite queries, retrieve matching records, and display the results in a responsive dashboard.&lt;/p&gt;

&lt;p&gt;The idea is simple: spend less time searching for outdoor activities and more time actually doing them.&lt;/p&gt;




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

&lt;h3&gt;
  
  
  Application Features
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Natural Language Search&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Users can enter questions directly into the search bar or choose from predefined example queries to get started.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. SQL Query Inspector&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The application displays the SQL generated by the model, allowing users to see how their natural language request was translated into a database query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Dynamic Results Table&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Results are displayed in a responsive table with formatting based on the returned data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Color-coded difficulty badges (Easy, Moderate, Hard).&lt;/li&gt;
&lt;li&gt;Readable boolean indicators (✅ Yes / ❌ No).&lt;/li&gt;
&lt;li&gt;Trail distances in miles.&lt;/li&gt;
&lt;li&gt;Location and activity information.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Loading and Error States&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The interface handles loading, empty results, and invalid queries with appropriate feedback.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Interaction
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;User input:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Show me easy trails under 3 miles with shade."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generated SQL:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;length_miles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;has_shade&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;location&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;trails&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;LOWER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;difficulty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'easy'&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;length_miles&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;has_shade&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example Results:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trail&lt;/th&gt;
&lt;th&gt;Distance&lt;/th&gt;
&lt;th&gt;Shade&lt;/th&gt;
&lt;th&gt;Location&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sunset Ridge Loop&lt;/td&gt;
&lt;td&gt;1.8 mi&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;Austin, TX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lady Bird Lake&lt;/td&gt;
&lt;td&gt;1.3 mi&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;Austin, TX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Piedmont Park Loop&lt;/td&gt;
&lt;td&gt;2.4 mi&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;Atlanta, GA&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The generated SQL is also visible in the interface, making the application's behavior easier to understand and debug.&lt;/p&gt;




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

&lt;p&gt;The project is open-source and organized as a full-stack monorepo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub Repository:&lt;/strong&gt; (&lt;a href="https://github.com/radhikaaa25/touch-grass" rel="noopener noreferrer"&gt;https://github.com/radhikaaa25/touch-grass&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  Tech Stack
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technologies&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Python 3.11+, FastAPI, Uvicorn&lt;/td&gt;
&lt;td&gt;REST API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI Agent&lt;/td&gt;
&lt;td&gt;LiteLLM, Gemini / Open-weight Llama&lt;/td&gt;
&lt;td&gt;Natural Language to SQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;SQLite3&lt;/td&gt;
&lt;td&gt;Outdoor activity storage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;React 19, Vite, Tailwind CSS v4&lt;/td&gt;
&lt;td&gt;User interface&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tooling&lt;/td&gt;
&lt;td&gt;Pydantic v2, TypeScript&lt;/td&gt;
&lt;td&gt;Data validation and type safety&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;The application follows a straightforward request-response pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             User
               |
               v
      React Frontend
               |
               v
        FastAPI Backend
               |
               v
       Text-to-SQL Agent
               |
               v
      LiteLLM Model Router
               |
               v
       Generated SQL Query
               |
               v
        Query Validation
               |
               v
         SQLite Database
               |
               v
         JSON Response
               |
               v
       Dynamic Results UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;h3&gt;
  
  
  1. Schema-Grounded Text-to-SQL
&lt;/h3&gt;

&lt;p&gt;One of the main challenges was making sure the language model generated queries using actual database tables and columns rather than inventing its own structure.&lt;/p&gt;

&lt;p&gt;To address this, the backend retrieves the SQLite schema and includes it in the agent's system prompt.&lt;/p&gt;

&lt;p&gt;The model receives both the database structure and a set of query-generation rules.&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;SYSTEM_PROMPT&lt;/span&gt; &lt;span class="o"&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 are a SQL query generator for an outdoor activities SQLite database.

DATABASE SCHEMA:
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;get_schema_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

RULES:
1. Output ONLY a single valid SQLite SELECT query.
2. Do not include markdown, code fences, or explanations.
3. Never generate INSERT, UPDATE, DELETE, DROP, ALTER, or CREATE statements.
4. Use only the tables and columns provided in the schema.
5. Boolean columns (has_shade, has_restrooms, allows_dogs)
   use 1 for true and 0 for false.
6. Use LOWER() for case-insensitive string comparisons.
7. Always include &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; and &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; in the results.
8. Limit results to a maximum of 50 rows.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps constrain the model's output and makes the generated queries more consistent with the available data.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Model-Agnostic Integration with LiteLLM
&lt;/h3&gt;

&lt;p&gt;I used &lt;code&gt;litellm&lt;/code&gt; to keep the application independent of a single LLM provider.&lt;/p&gt;

&lt;p&gt;The backend can be configured to use Google Gemini, local open-weight models through Ollama, or supported cloud-hosted models through providers such as Groq.&lt;/p&gt;

&lt;p&gt;The model can be changed through an environment variable without rewriting the agent logic.&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;litellm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;completion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SYSTEM_PROMPT&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;question&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This also makes it possible to experiment with different models and compare their Text-to-SQL performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. SQL Validation and Error Handling
&lt;/h3&gt;

&lt;p&gt;Since the SQL is generated by a language model, it needs to be checked before execution.&lt;/p&gt;

&lt;p&gt;The backend includes a validation layer that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Removes surrounding Markdown code fences when present.&lt;/li&gt;
&lt;li&gt;Checks that the generated query begins with &lt;code&gt;SELECT&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Rejects queries that do not satisfy the expected format.&lt;/li&gt;
&lt;li&gt;Handles SQLite execution errors using &lt;code&gt;try/except sqlite3.Error&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Returns readable error messages to the frontend.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These checks provide an initial safeguard against unintended queries. For a production deployment, I would strengthen this further with SQLite read-only connections, single-statement enforcement, and stricter SQL validation rather than relying on prompt instructions or prefix checks alone.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Building the Frontend
&lt;/h3&gt;

&lt;p&gt;I wanted the interface to feel like an outdoor discovery tool rather than a conventional database search application.&lt;/p&gt;

&lt;p&gt;The frontend uses React, Vite, and Tailwind CSS with an earth-toned visual theme.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Design choices:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Forest greens (&lt;code&gt;#1d3818&lt;/code&gt; to &lt;code&gt;#8dba7e&lt;/code&gt;), bark browns, and soft sky accents.&lt;/li&gt;
&lt;li&gt;A prominent natural-language search bar.&lt;/li&gt;
&lt;li&gt;Example query chips for first-time users.&lt;/li&gt;
&lt;li&gt;A terminal-inspired SQL inspector.&lt;/li&gt;
&lt;li&gt;Dynamically generated result columns based on the API response.&lt;/li&gt;
&lt;li&gt;Custom formatting for distances, difficulty levels, and boolean fields.&lt;/li&gt;
&lt;li&gt;Responsive layouts for different screen sizes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The frontend does not need to know which database table the user is querying beforehand. It builds the results table from the returned column names and values.&lt;/p&gt;

&lt;p&gt;This allows the same interface to display trails, parks, and running clubs without separate result components for every category.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Open Innovation Matters
&lt;/h2&gt;

&lt;p&gt;I wanted Touch Grass to be easy to run, modify, and extend without depending entirely on proprietary services.&lt;/p&gt;

&lt;p&gt;Three aspects of open innovation influenced the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Local Model Support and Privacy
&lt;/h3&gt;

&lt;p&gt;Outdoor discovery applications can involve location information and personal activity preferences.&lt;/p&gt;

&lt;p&gt;By supporting local models through Ollama, Touch Grass provides an option to process natural-language queries locally instead of sending them to a cloud-hosted LLM.&lt;/p&gt;

&lt;p&gt;This gives developers more control over where their data is processed.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Flexibility Across AI Providers
&lt;/h3&gt;

&lt;p&gt;Using LiteLLM allows developers to experiment with different supported models without changing the application's core architecture.&lt;/p&gt;

&lt;p&gt;Someone running the project locally can choose an open-weight model, while another developer can configure a hosted provider.&lt;/p&gt;

&lt;p&gt;The application is not tied to one model or vendor.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Community-Driven Outdoor Data
&lt;/h3&gt;

&lt;p&gt;SQLite provides a lightweight starting point for maintaining a curated collection of trails, parks, and running clubs.&lt;/p&gt;

&lt;p&gt;The project can be extended with additional locations, activity categories, and community-contributed datasets.&lt;/p&gt;

&lt;p&gt;The goal is to make outdoor discovery accessible and adaptable to different cities and communities.&lt;/p&gt;




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

&lt;p&gt;I used &lt;strong&gt;Google DeepMind Antigravity&lt;/strong&gt; during development to assist with scaffolding, implementation, and debugging.&lt;/p&gt;

&lt;p&gt;The development process involved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up the FastAPI and React monorepo.&lt;/li&gt;
&lt;li&gt;Implementing the Text-to-SQL agent and database integration.&lt;/li&gt;
&lt;li&gt;Building the search interface and dynamic results table.&lt;/li&gt;
&lt;li&gt;Resolving Python dependency and virtual environment configuration issues.&lt;/li&gt;
&lt;li&gt;Testing backend functionality and verifying the frontend build.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Antigravity was useful for iterating across the backend and frontend while keeping the application architecture consistent.&lt;/p&gt;




&lt;h2&gt;
  
  
  Challenges and Learnings
&lt;/h2&gt;

&lt;p&gt;The most interesting part of building Touch Grass was connecting natural-language input to structured database operations.&lt;/p&gt;

&lt;p&gt;A few key takeaways:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Schema context matters.&lt;/strong&gt; Providing the model with the actual database structure makes Text-to-SQL generation more reliable than relying on generic instructions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LLM output still needs validation.&lt;/strong&gt; Even with explicit prompting, generated SQL should be treated as untrusted input.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model flexibility is useful.&lt;/strong&gt; Separating the model provider from the application logic makes experimenting with local and hosted models significantly easier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A simple interface can hide a fairly interesting backend.&lt;/strong&gt; From the user's perspective, the entire workflow is just asking a question and viewing matching outdoor activities.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;Some improvements I'd like to explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integrating OpenStreetMap data for broader location coverage.&lt;/li&gt;
&lt;li&gt;Adding geolocation-based searches for nearby trails and parks.&lt;/li&gt;
&lt;li&gt;Supporting community submissions for new outdoor locations.&lt;/li&gt;
&lt;li&gt;Improving SQL validation and database access restrictions.&lt;/li&gt;
&lt;li&gt;Testing Text-to-SQL accuracy across different open-weight models.&lt;/li&gt;
&lt;li&gt;Adding map-based visualization alongside the existing results table.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;&lt;strong&gt;Primary Challenge:&lt;/strong&gt; Hacktoberfest Week 1 – Touch Grass&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Featured Categories:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Best Use of Open-Source AI / Open Weights&lt;/li&gt;
&lt;li&gt;Full-Stack Developer Experience&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Built with Python, React, SQLite, and LiteLLM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Less scrolling. More strolling. 🌿&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Source code: &lt;a href="https://github.com/radhikaaa25/touch-grass" rel="noopener noreferrer"&gt;GitHub – Touch Grass&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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