<?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: Prathamesh Anvekar</title>
    <description>The latest articles on DEV Community by Prathamesh Anvekar (@prathamanvekar).</description>
    <link>https://dev.to/prathamanvekar</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%2F2067975%2F0b760f91-64cf-4294-9b2f-74acbf8e586a.jpg</url>
      <title>DEV Community: Prathamesh Anvekar</title>
      <link>https://dev.to/prathamanvekar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/prathamanvekar"/>
    <language>en</language>
    <item>
      <title>Building a Secure LLM Proxy with Fine-Tuned Gemma 3 for Production Applications</title>
      <dc:creator>Prathamesh Anvekar</dc:creator>
      <pubDate>Sun, 18 Oct 2026 07:46:58 +0000</pubDate>
      <link>https://dev.to/prathamanvekar/building-a-secure-llm-proxy-with-fine-tuned-gemma-3-for-production-applications-2fdj</link>
      <guid>https://dev.to/prathamanvekar/building-a-secure-llm-proxy-with-fine-tuned-gemma-3-for-production-applications-2fdj</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;Over the past year, many freelance developers, small agencies, and independent builders have integrated LLM capabilities into their client work. Whether creating customer intake assistants, contract summarizers, or invoice extractors, clients increasingly expect AI-driven workflows.&lt;/p&gt;

&lt;p&gt;However, deploying generative models in client-facing environments introduces several practical operational and compliance challenges. Clients and end users frequently paste sensitive personal data - including customer contact information, phone numbers, and production API credentials - directly into prompt inputs. Input fields are also vulnerable to adversarial prompt injections designed to bypass system instructions. In addition, document analysis workflows can be targeted with hidden or low-contrast text embedded within PDFs and images, potentially hijacking downstream reasoning.&lt;/p&gt;

&lt;p&gt;While enterprise AI security platforms exist, they are typically aimed at large organizations with corresponding price points and complex onboarding processes. For independent developers and small software studios delivering custom applications on modest budgets, these enterprise solutions are often impractical.&lt;/p&gt;

&lt;p&gt;I built AEGIS as a lightweight, drop-in security proxy that developers can place in front of their LLM endpoints. It acts as an intermediary gateway that sanitizes personal data in real time, inspects and OCRs uploaded documents, evaluates prompt safety using an open-source fine-tuned Gemma 3 model, and provides sanitized web retrieval through SerpApi. For agencies and independent contractors, this provides a straightforward security layer that can be offered to clients as a paid compliance add-on or hosted as a managed micro-service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Incoming Untrusted Payload (Text / PDF / Image / Web Search)
                        │
                        ▼
   [ Layer 1: Magika Deep MIME &amp;amp; Polyglot Verification ]
                        │
                        ▼
   [ Layer 2: Dual-Stream OCR &amp;amp; Hidden Text Extractor ]
                        │
                        ▼
   [ Layer 3: Context-Aware Presidio + Regex PII Scrubber ]
           (Transforms PII -&amp;gt; &amp;lt;EMAIL&amp;gt;, &amp;lt;PHONE&amp;gt;, &amp;lt;API_KEY&amp;gt;)
                        │
                        ▼
   [ Layer 4: Fine-Tuned Gemma 3 / LoRA Safety Classifier ]
           (Detects Prompt Injections &amp;amp; Malicious Payloads)
                        │
                        ▼
   [ Layer 5: Sanitized Web Retrieval via SerpApi ]
           (Filters Poisoned Knowledge Blocks &amp;amp; Injections)
                        │
                        ▼
      Clean, Verified Context -&amp;gt; Target LLM -&amp;gt; User
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The gateway handles inbound requests across multiple input types. Plain text prompts are stripped of credentials and personal identifiers before being evaluated by the safety classifier. File uploads undergo deep MIME verification and visual OCR to detect obscured text before text extraction proceeds. When web search augmentation is enabled, SerpApi results are retrieved and scrubbed before being appended to the model context. A web dashboard provides real-time visibility into each verification step, showing exactly what data was modified and why.&lt;/p&gt;


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

&lt;p&gt;The application provides an interactive interface built to demonstrate each stage of the proxy pipeline. Users can enter raw prompts, upload documents, or toggle web augmentation while observing how the system handles the input.&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%2Fk2dt6syf3xat01p063og.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%2Fk2dt6syf3xat01p063og.png" alt="AEGIS Dashboard and Security Pipeline" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When a request is submitted, the interface displays the immediate verdict from the fine-tuned Gemma 3 classifier alongside a detailed breakdown of the sanitization process. Original text and redacted text are presented side by side, highlighting replaced entity tags such as email addresses, phone numbers, and API tokens. For file submissions, the system displays the extracted text alongside confidence scores from the OCR and file analysis stages. The dashboard also includes reference summaries of recent real-world security incidents, such as source code leaks and exposed credentials, to provide practical context for why these protective layers are necessary in production software.&lt;/p&gt;


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

&lt;p&gt;The complete source code is available on GitHub at &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/prathamanvekar" rel="noopener noreferrer"&gt;
        prathamanvekar
      &lt;/a&gt; / &lt;a href="https://github.com/prathamanvekar/secure-llm-proxy" rel="noopener noreferrer"&gt;
        secure-llm-proxy
      &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&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;AEGIS 🛡️&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Guardian for your LLMs - A secure, production-ready AI gateway with multi-layer defensive sanitization.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An open-weight, privacy-first proxy that intercepts sensitive PII, neutralizes prompt injections, de-weaponizes uploaded documents, and filters web context using a fine-tuned Gemma 3 model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.python.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a6a2871274b67bcbf622f01ba9bbd1089e917138d362a82fb237e258d55fcde6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d332e31302b2d3337373641423f7374796c653d666c6174266c6f676f3d707974686f6e266c6f676f436f6c6f723d7768697465" alt="Python"&gt;&lt;/a&gt;
&lt;a href="https://fastapi.tiangolo.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/22d1011093eea52fa5123614883ccd664de0c226b45b63c5e64b32b974fd1a04/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f466173744150492d302e3131302b2d3030393638383f7374796c653d666c6174266c6f676f3d66617374617069266c6f676f436f6c6f723d7768697465" alt="FastAPI"&gt;&lt;/a&gt;
&lt;a href="https://huggingface.co/google/gemma-3-4b-it" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1267ce0ded8ab3929edf24c3ac34dc07810a7a1f758e3264ba8591ea26fef9ff/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d6f64656c2d47656d6d615f335f46696e652d2d54756e65642d3943323742303f7374796c653d666c6174266c6f676f3d676f6f676c65266c6f676f436f6c6f723d7768697465" alt="Model"&gt;&lt;/a&gt;
&lt;a href="https://github.com/huggingface/peft" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8cc6298b2438742c3beca5ca44f04bf7ecc7da0c7e0a553ae02439d316b074a7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f496e666572656e63652d342d2d6269745f4c6f52412d626c75653f7374796c653d666c6174" alt="Inference"&gt;&lt;/a&gt;
&lt;a href="https://microsoft.github.io/presidio/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4da6a75f25d70a330ec9a4f72760e8b2db6414a7c8ec2ef5bd182479559f5264/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5049492d507265736964696f2d3030373844343f7374796c653d666c6174266c6f676f3d6d6963726f736f6674266c6f676f436f6c6f723d7768697465" alt="PII"&gt;&lt;/a&gt;
&lt;a href="https://vitejs.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/65410f65bae228b7fdda02f71a1d256616401388fd28523a92d386d4c1437347/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f46726f6e74656e642d52656163745f2b5f566974652d3631444146423f7374796c653d666c6174266c6f676f3d7265616374266c6f676f436f6c6f723d626c61636b" alt="Frontend"&gt;&lt;/a&gt;
&lt;a href="https://hacktoberfest.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/77b1e3d478e311f3f7c24ea455efbb9181b4b799dc0fde3c9b6dfba0f063d523/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4861636b746f626572666573742d323032362d4637343730303f7374796c653d666c6174266c6f676f3d6861636b746f62657266657374266c6f676f436f6c6f723d7768697465" alt="Hacktoberfest"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/prathamanvekar/secure-llm-proxy#overview" rel="noopener noreferrer"&gt;Overview&lt;/a&gt; • &lt;a href="https://github.com/prathamanvekar/secure-llm-proxy#architecture" rel="noopener noreferrer"&gt;Architecture&lt;/a&gt; • &lt;a href="https://github.com/prathamanvekar/secure-llm-proxy#key-features" rel="noopener noreferrer"&gt;Key Features&lt;/a&gt; • &lt;a href="https://github.com/prathamanvekar/secure-llm-proxy#tech-stack" rel="noopener noreferrer"&gt;Tech Stack&lt;/a&gt; • &lt;a href="https://github.com/prathamanvekar/secure-llm-proxy#quickstart" rel="noopener noreferrer"&gt;Quickstart&lt;/a&gt; • &lt;a href="https://github.com/prathamanvekar/secure-llm-proxy#verification" rel="noopener noreferrer"&gt;Verification&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Overview&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;As generative AI transitions into production workflows, organizations face several critical operational risks: accidental exposure of personal identifiable information (PII), adversarial prompt injections designed to hijack model instructions, and malicious payloads hidden within uploaded files or untrusted web context.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AEGIS&lt;/strong&gt; provides an automated security proxy that sits between client applications and downstream models. It cleans inbound prompts, redacts sensitive credentials and contact data, inspects multi-format documents using dual-stream OCR, classifies injection threats using an open-source fine-tuned &lt;strong&gt;Gemma 3&lt;/strong&gt; model, and sanitizes web knowledge retrieved through &lt;strong&gt;SerpApi&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Zero Trust AI Gateway:&lt;/strong&gt; Raw client prompts, uploaded documents…&lt;/p&gt;
&lt;/blockquote&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/prathamanvekar/secure-llm-proxy" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
. The repository includes the FastAPI gateway implementation in &lt;code&gt;backend.py&lt;/code&gt;, the training and inference notebook for fine-tuning Gemma 3 in &lt;code&gt;backend notebook/aegis-server-wow-verse-mmcoe.ipynb&lt;/code&gt;, and the frontend interface in the &lt;code&gt;src/&lt;/code&gt; directory.


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

&lt;p&gt;AEGIS is structured around an asynchronous multi-layer pipeline combining open-source models, parsing utilities, and structured validation routines.&lt;/p&gt;

&lt;p&gt;At the core of the system is a fine-tuned Google Gemma 3 open-weight model (&lt;code&gt;gemma-safety-classifier&lt;/code&gt;). Using open weights was central to this project because safety classification needs to be fast, deterministic, and free of per-token API charges. I fine-tuned Gemma 3 using Low-Rank Adaptation (LoRA) through the PEFT library, training it specifically to evaluate user prompts and classify them into discrete categories including safe prompts, prompt injections, cybercrime or malware payloads, and general policy violations. To keep memory utilization minimal while maintaining classification accuracy, the model runs with 4-bit NormalFloat quantization through BitsAndBytes:&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="c1"&gt;# Quantized loading of the fine-tuned Gemma 3 safety classifier
&lt;/span&gt;&lt;span class="n"&gt;bnb_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BitsAndBytesConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;load_in_4bit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;bnb_4bit_use_double_quant&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;bnb_4bit_quant_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nf4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;bnb_4bit_compute_dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bfloat16&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;peft_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PeftConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;base_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AutoModelForCausalLM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;peft_config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;base_model_name_or_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quantization_config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bnb_config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;torch_dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bfloat16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;trust_remote_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;low_cpu_mem_usage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PeftModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;By deploying the fine-tuned Gemma 3 model directly within the proxy, the system evaluates inputs deterministically without routing them to third-party providers. The model is paired with a lightweight heuristic check for common benign drafting requests, ensuring that standard creative writing tasks pass through without unnecessary latency.&lt;/p&gt;

&lt;p&gt;File uploads introduce an attack surface where malicious instructions can be hidden inside documents. To handle this, AEGIS uses Google Magika to inspect byte headers and confirm that files match their claimed extensions. When processing PDFs, the system uses a dual-stream parsing approach: &lt;code&gt;pdfplumber&lt;/code&gt; extracts standard textual content, while &lt;code&gt;pdf2image&lt;/code&gt; renders each page into an image for OCR evaluation using Tesseract and EasyOCR. This allows the system to catch adversarial techniques such as zero-opacity fonts, off-canvas text, or white-on-white text that bypass typical text parsers.&lt;/p&gt;

&lt;p&gt;Personal data sanitization runs through Microsoft Presidio combined with targeted regular expressions. The pipeline identifies emails, phone numbers, credit card numbers, US Social Security numbers, IBANs, and common API key patterns, replacing them with standardized placeholders such as &lt;code&gt;&amp;lt;EMAIL&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;API_KEY&amp;gt;&lt;/code&gt; before text reaches any downstream LLM:&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;sanitize_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&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;Dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;regex_cleaned&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;regex_sanitize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;HIGH_RISK&lt;/span&gt; &lt;span class="o"&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;EMAIL_ADDRESS&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;PHONE_NUMBER&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;CREDIT_CARD&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;API_KEY&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;IBAN&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;US_SSN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;final_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;presidio_findings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;presidio_redact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regex_cleaned&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;redact_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HIGH_RISK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;original&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;final_sanitized&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;final_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;presidio_findings&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;presidio_findings&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For applications requiring external knowledge retrieval, AEGIS integrates SerpApi to query Google Search. Rather than passing raw search results directly into the prompt context, AEGIS extracts organic search snippets, question summaries, and overview blocks, running each text fragment through the fine-tuned Gemma 3 classifier and PII sanitizer before assembling the final reference block. This mitigates indirect prompt injection from untrusted external websites:&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;secure_serp_knowledge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&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;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;raw_blocks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extract_knowledge_from_serp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;safe_blocks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;raw_blocks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;threat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;detect_prompt_injection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;threat&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SAFE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;continue&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;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;safe_blocks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&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;safe_blocks&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;For a developer tool designed as a sustainable side project, using open-source AI is what makes the architecture viable both technically and commercially.&lt;/p&gt;

&lt;p&gt;First, open weights make the unit economics predictable. If a security proxy had to invoke a closed commercial API to evaluate every incoming prompt, inference costs would scale directly with volume. A client sending hundreds of thousands of requests per month would generate significant API bills, eroding the margins of a flat-rate subscription. By running a fine-tuned Gemma 3 model in 4-bit precision, inference runs on accessible consumer or cloud GPU hardware with zero marginal cost per request.&lt;/p&gt;

&lt;p&gt;Second, open models uphold genuine data privacy. Routing unvetted user prompts containing confidential customer information to a third-party proprietary API simply to check for sensitive data creates the very exposure problem the tool is meant to solve. Running an open-source model locally or in a dedicated private environment ensures that raw customer data never leaves the developer's controlled infrastructure.&lt;/p&gt;

&lt;p&gt;Finally, open innovation enables task-specific fine-tuning. General-purpose proprietary models are designed to balance broad conversational capabilities, making them prone to either over-refusing benign technical prompts or missing specialized adversarial injection techniques. Having direct access to Gemma 3 allowed me to fine-tune the weights on dedicated security and prompt injection datasets, resulting in a compact, highly focused classifier that performs its specific role reliably.&lt;/p&gt;


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

&lt;p&gt;To test AEGIS in a real-world workflow, I shared an instance with an independent developer who builds intake chatbots and document summarization tools for local accounting clients. His primary concern was handling client tax documents where individuals frequently paste sensitive identity numbers or confidential notes into unstructured form fields.&lt;/p&gt;

&lt;p&gt;We configured his development environment to route test requests through AEGIS. During testing, he submitted sample tax summaries containing mock Social Security numbers and phone numbers, as well as test documents with hidden prompt injection overrides. AEGIS redacted the personal data into standardized tokens before passing the text to the summarizer, and successfully flagged the injection attempts without disrupting normal queries.&lt;/p&gt;

&lt;p&gt;Based on the testing, he noted that having an auditable sanitization layer reduced the compliance risk of offering AI features to his clients. He indicated he would pay a monthly fee of $45 to route his production client applications through a hosted instance of the proxy, and suggested adding webhook alerts to notify his team via Slack whenever a prompt injection attempt is intercepted.&lt;/p&gt;


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


&lt;div class="ltag-agent-session"&gt;
  &lt;div class="agent-session-header"&gt;
    
    &lt;span class="agent-session-tool-icon-badge" title="Gemini CLI"&gt;
&lt;/span&gt;
    &lt;span class="agent-session-title"&gt;Building Feels: Local AI Soundtrack Matcher for Outdoor Spaces&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;Hacktoberfest Dev Challenge: Touch Grass. Build an open-source AI project that gets people off the screen and into the real world, running open-weight models locally with privacy and grounded discovery.&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;Designing Feels: a local, privacy-first web application that turns recent Spotify listening history into curated outdoor nature destinations. Architecture uses local Qwen 2.5 Coder 7B via Ollama for mood synthesis, SerpApi for grounded Google Maps venue discovery, SQLite WAL mode for deterministic caching and rate limiting, and editorial neobrutalism UI.&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-runtests"&gt;run_tests&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;python -m pytest tests -v&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"&gt;&lt;code&gt;python -m pytest tests -v&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;21 passed in 2.75s&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;Separate the Landing Page and the App. After connecting to Spotify, redirect to the main app with a 4-stage data processing indicator before beautifully revealing the outdoor recommendations. Rename the app to Feels.&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;Segregated editorial landing page at / and application dashboard at /app. Integrated real-time 4-stage processing progress bar (track reading, local Qwen inference, SerpApi discovery, and grounding), updated branding to Feels, migrated SQLite to feels.db, and verified 15/day quota enforcement.&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;
        4 of 4 messages
    &lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;






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

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

&lt;p&gt;AEGIS uses a fine-tuned Google Gemma 3 open-weight model as its central security classifier. Trained with LoRA adapters and running with 4-bit quantization, Gemma 3 provides deterministic, low-latency classification for prompt injections, malware payloads, and unsafe requests without relying on closed cloud moderation APIs.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Feels: Translating Your Spotify Soundtrack into Real Outdoor Places with Local AI and SerpApi</title>
      <dc:creator>Prathamesh Anvekar</dc:creator>
      <pubDate>Fri, 09 Oct 2026 21:49:14 +0000</pubDate>
      <link>https://dev.to/prathamanvekar/feels-translating-your-spotify-soundtrack-into-real-outdoor-places-with-local-ai-and-serpapi-5e0d</link>
      <guid>https://dev.to/prathamanvekar/feels-translating-your-spotify-soundtrack-into-real-outdoor-places-with-local-ai-and-serpapi-5e0d</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;Like many developers, I spend hours locked in a sensory bubble at my desk with noise-canceling headphones on, cycling through music while deep in code. Over time, I noticed something undeniable about my daily Spotify queue: my listening history serves as an unfiltered mirror of my mental state and fatigue. When hunting subtle bugs or sprinting against deadlines, my queue naturally shifts to driving, high-tempo electronica. When unwinding after a long refactoring session or mapping system architecture, it settles into minimalist acoustic or atmospheric ambient soundscapes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Session Window (Last 10 Tracks):
- M83: Midnight City -&amp;gt; 105 BPM, expansive synth wave, high kinetic momentum
- Justice: Genesis -&amp;gt; 117 BPM, distorted analog bass, aggressive forward drive
- The xx: Intro -&amp;gt; 100 BPM, minimalist reverberation, steady contemplative pace
- The Prodigy: Breathe -&amp;gt; 130 BPM, breakbeat rhythm, peak adrenaline burst
- Woodkid: Run Boy Run -&amp;gt; 132 BPM, marching orchestral drums, surging forward drive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Streaming algorithms take this behavioral data and use it to feed more screen addiction, building autoplay queues engineered to keep you in your chair. The moment you push your commits, you close your editor only to open social feeds or video streams instead of getting fresh air.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;Feels&lt;/strong&gt; to turn that dynamic around: using your soundtrack as a natural bridge to step away from your desk and reconnect with the outdoors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Feels&lt;/strong&gt; is a web application that takes your recent Spotify listening session and interprets its acoustic cadence, energy density, and emotional texture using an open-weight model running locally on your hardware. Rather than trapping you in a conversational chatbot loop, it acts as an environmental scout. It maps your sonic state to geographic search intents, then uses &lt;strong&gt;SerpApi's Google Maps engine&lt;/strong&gt; to find three verified real-world outdoor destinations - such as elevated ridgeline trails, shaded forest loops, or tranquil lakeside parks. Each spot includes verified user ratings, review counts, photos, a grounded explanation of why it fits your current soundtrack, and one-click Google Maps directions.&lt;/p&gt;

&lt;p&gt;To ensure the screen stays the shortest part of the experience, the application enforces a strict cap of 15 refreshes per day. You check your curated spots, pick a trail, shut the laptop, and head outside.&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Here is a walkthrough of Feels in action, showing the Spotify authorization, the live four-stage processing indicator, and the resulting outdoor trail cards:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdvzdcjptuec6ewdsr7qh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdvzdcjptuec6ewdsr7qh.gif" alt="Feels Project Demo" width="480" height="270"&gt;&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/prathamanvekar" rel="noopener noreferrer"&gt;
        prathamanvekar
      &lt;/a&gt; / &lt;a href="https://github.com/prathamanvekar/feels" rel="noopener noreferrer"&gt;
        feels
      &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&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Feels 🌿&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Turn your music into a reason to get outside.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An open-weight, privacy-first web application that translates your recent Spotify listening history into curated outdoor destinations using on-device AI and real-time map discovery.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://python.org" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ae0e75b155a31adbd0bbcaaef1a5dd5b6100ea769df96a517ecd5d9325997a3f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d332e31302532422d3337373641423f7374796c653d666c61742d737175617265266c6f676f3d707974686f6e266c6f676f436f6c6f723d7768697465" alt="Python"&gt;&lt;/a&gt;
&lt;a href="https://fastapi.tiangolo.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/59537c9a5b69c2f4d2a388b37916a561ad0f9b3d1e7143dfae3f0fba09205b24/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f466173744150492d302e3131302532422d3030393638383f7374796c653d666c61742d737175617265266c6f676f3d66617374617069266c6f676f436f6c6f723d7768697465" alt="FastAPI"&gt;&lt;/a&gt;
&lt;a href="https://ollama.com" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1f2fd29a6d1f0efbc475bf9ef9ae6bea9f8baef548b7dd479aaf00e69e0adfbb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4f6c6c616d612d4c6f63616c5f496e666572656e63652d626c61636b3f7374796c653d666c61742d737175617265266c6f676f3d6f6c6c616d61266c6f676f436f6c6f723d7768697465" alt="Ollama"&gt;&lt;/a&gt;
&lt;a href="https://huggingface.co/Qwen" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bf966357047e8ba8976e1f7326fa11218f4a3f51be2fd481c663b2fb11c70aa9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d6f64656c2d5177656e5f322e355f436f6465725f37422d626c756576696f6c65743f7374796c653d666c61742d737175617265" alt="Model"&gt;&lt;/a&gt;
&lt;a href="https://github.com/prathamanvekar/feels/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/152aa2a37725b9fd554b28ff24d270f6071c67927a63e6d635a55c8e188e20c7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e3f7374796c653d666c61742d737175617265" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://dev.to/challenges/hf26" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/4c076d54afb49f8a31359423caace7aed67d022548b104faffdbe91f43fe9bae/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4861636b746f626572666573742d323032362d6f72616e67653f7374796c653d666c61742d737175617265" alt="Hacktoberfest"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/prathamanvekar/feels#quickstart" rel="noopener noreferrer"&gt;Live Demo&lt;/a&gt; • &lt;a href="https://github.com/prathamanvekar/feels#architecture" rel="noopener noreferrer"&gt;Architecture&lt;/a&gt; • &lt;a href="https://github.com/prathamanvekar/feels#configuration" rel="noopener noreferrer"&gt;Configuration&lt;/a&gt; • &lt;a href="https://github.com/prathamanvekar/feels#deployment" rel="noopener noreferrer"&gt;Deployment&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Overview&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Most streaming apps use your listening history to feed more screen time, generating algorithmic queues engineered to keep you in your chair.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Feels&lt;/strong&gt; flips that dynamic around.&lt;/p&gt;
&lt;p&gt;Instead of another chatbot or infinite playlist, Feels treats your recent soundtrack as an unfiltered mirror of your mental headspace. It reads your 10 most recent tracks once per day, runs an open-weight model (&lt;strong&gt;Qwen 2.5 Coder 7B&lt;/strong&gt;) locally on your machine to analyze tempo, energy density, and emotional cadence, and grounds that mood in real-world outdoor spaces using &lt;strong&gt;SerpApi's Google Maps engine&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You get three curated physical destinations - elevated ridge trails, shaded forest loops, or…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/prathamanvekar/feels" 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 system is designed as an end-to-end pipeline connecting audio streaming telemetry, private on-device reasoning, and grounded spatial exploration. When users open the app, a real-time four-stage status pipeline visualizes the progress as tracks are fetched, analyzed on-device, queried spatially, and curated:&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%2F6gqbpo0jidls8z8r9zbz.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%2F6gqbpo0jidls8z8r9zbz.png" alt="Feels Architecture Diagram" width="800" height="253"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Data ingestion begins with the &lt;strong&gt;Spotify Web API&lt;/strong&gt;, authenticating users via OAuth 2.0 with the &lt;code&gt;user-read-recently-played&lt;/code&gt; scope. Rather than polling continuously, Feels retrieves your ten most recently played tracks at most once per calendar day. The backend extracts essential track attributes, artist metadata, and timestamps to evaluate pacing and acoustic density while keeping external requests to a minimum. These tracks are hashed and stored in an embedded SQLite database (&lt;code&gt;feels.db&lt;/code&gt;), ensuring that subsequent refreshes throughout the day never spam Spotify servers.&lt;/p&gt;

&lt;p&gt;To translate raw music tracks into an outdoor setting, Feels runs &lt;strong&gt;Qwen 2.5 Coder 7B&lt;/strong&gt; locally through &lt;strong&gt;Ollama&lt;/strong&gt; on localhost port 11434. Instead of open-ended conversational completions, the model is constrained to output a strict JSON schema containing acoustic energy levels, dominant emotional descriptors, and targeted spatial search queries:&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="c1"&gt;# Querying local Ollama with JSON schema enforcement and defensive extraction
&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&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;model&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;qwen2.5-coder:7b&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;prompt&lt;/span&gt;&lt;span class="sh"&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="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ENVIRONMENTAL_PSYCHOLOGY_PROMPT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;Recent listening session:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tracklist_text&lt;/span&gt;&lt;span class="si"&gt;}&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;stream&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;format&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;json&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;options&lt;/span&gt;&lt;span class="sh"&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;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;top_p&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;num_predict&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;700&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;httpx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AsyncClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;60.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://127.0.0.1:11434/api/generate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;analysis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extract_and_validate_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&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="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Those environmental queries feed directly into &lt;strong&gt;SerpApi's Google Maps engine&lt;/strong&gt; to retrieve genuine physical places with verified ratings, reviews, and geographic coordinates. The SQLite cache deduplicates visited spots so each refresh rotates to fresh outdoor locations. For cloud hosting and continuous deployment, Feels includes a native &lt;code&gt;render.yaml&lt;/code&gt; blueprint, allowing it to deploy seamlessly to &lt;strong&gt;Render&lt;/strong&gt; as a Python web service with automatic dependency installation, persistent environment variables, and live health monitoring via &lt;code&gt;/api/health&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Listening history is personal behavioral telemetry. What someone plays during late-night debugging or high-pressure sprints reflects their emotional state, stress levels, and daily habits. Routing raw listening history to third-party commercial AI providers exposes private behavioral patterns to corporate tracking pipelines. Running an open-weight model locally ensures that private listening data never leaves the developer's laptop, transmitting only generalized, non-identifying outdoor search terms to map services.&lt;/p&gt;

&lt;p&gt;Open innovation also eliminates recurring token anxiety. When small personal utilities depend on metered cloud APIs, every casual refresh incurs a monetary penalty. Running open-weight models on consumer hardware provides predictable, deterministic inference at zero marginal cost, enabling sustainable tools that cost nothing to operate.&lt;/p&gt;

&lt;p&gt;Finally, outdoor exploration often takes place near hill ridgelines, nature sanctuaries, and forest paths where mobile reception is weak or unavailable. Because Feels combines local Ollama inference with persistent SQLite caching, the core mood profiling and trail guidance continue to function smoothly even when disconnected from the network.&lt;/p&gt;
&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;


&lt;div class="ltag-agent-session"&gt;
  &lt;div class="agent-session-header"&gt;
    
    &lt;span class="agent-session-tool-icon-badge" title="Gemini CLI"&gt;
&lt;/span&gt;
    &lt;span class="agent-session-title"&gt;Building Feels: Local AI Soundtrack Matcher for Outdoor Spaces&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;Hacktoberfest Dev Challenge: Touch Grass. Build an open-source AI project that gets people off the screen and into the real world, running open-weight models locally with privacy and grounded discovery.&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;Designing Feels: a local, privacy-first web application that turns recent Spotify listening history into curated outdoor nature destinations. Architecture uses local Qwen 2.5 Coder 7B via Ollama for mood synthesis, SerpApi for grounded Google Maps venue discovery, SQLite WAL mode for deterministic caching and rate limiting, and editorial neobrutalism UI.&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-runtests"&gt;run_tests&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;python -m pytest tests -v&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"&gt;&lt;code&gt;python -m pytest tests -v&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;21 passed in 2.75s&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;Separate the Landing Page and the App. After connecting to Spotify, redirect to the main app with a 4-stage data processing indicator before beautifully revealing the outdoor recommendations. Rename the app to Feels.&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;Segregated editorial landing page at / and application dashboard at /app. Integrated real-time 4-stage processing progress bar (track reading, local Qwen inference, SerpApi discovery, and grounding), updated branding to Feels, migrated SQLite to feels.db, and verified 15/day quota enforcement.&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;
        4 of 4 messages
    &lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;



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

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

</description>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>devchallenge</category>
    </item>
    <item>
      <title>Turning metacognition notes to your competitive programming coach</title>
      <dc:creator>Prathamesh Anvekar</dc:creator>
      <pubDate>Mon, 05 Oct 2026 00:11:51 +0000</pubDate>
      <link>https://dev.to/prathamanvekar/turning-metacognition-notes-to-your-competitive-programming-coach-12lg</link>
      <guid>https://dev.to/prathamanvekar/turning-metacognition-notes-to-your-competitive-programming-coach-12lg</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 friend &lt;strong&gt;Ved&lt;/strong&gt; and I have been grinding competitive programming together for months. After discussing Colin Galen's video on how top competitors dissect their practice, we started doing something specific: keeping a text file open while solving LeetCode and Codeforces problems to record &lt;strong&gt;timestamped "metacognition notes"&lt;/strong&gt; of our thoughts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0:00 - read problem statement. contiguous subarrays with k distinct elements.
0:03 - thought about standard sliding window with two pointers.
0:06 - issue: how to count *exact* k without missing smaller left bounds?
0:12 - stuck trying to rewind left pointer. count gets messy with duplicates.
0:18 - breakthrough: exact(k) = atMost(k) - atMost(k - 1)!
0:25 - wrote helper, tested edge cases, submitted -&amp;gt; Accepted.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;These notes capture our real-time &lt;strong&gt;cognitive blindspots&lt;/strong&gt; - the exact minute we got confused, the false paths we went down, and the habits that cost us time, like jumping straight into code before proving invariants. But the moment a problem was accepted, we always discarded them.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;cpmeta&lt;/strong&gt; for Ved and myself to stop that hard-earned data from going to waste.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;cpmeta&lt;/strong&gt; is a project that analyzes raw thinking notes alongside the problem statement using an open-weight LLM. Instead of just handing you an algorithmic solution, it acts like an &lt;strong&gt;ICPC coach&lt;/strong&gt; reviewing your thought process. It calculates exactly how long you stalled and diagnoses the &lt;strong&gt;root cause&lt;/strong&gt;, such as missing a monotonic reduction trick. It also detects recurring &lt;strong&gt;cognitive traps&lt;/strong&gt;, like abandoning valid approaches too early or overlooking problem constraints. Over time, it aggregates data across all your logged sessions to generate a &lt;strong&gt;prioritized study plan&lt;/strong&gt; that highlights your persistent topic weaknesses and proven strengths.&lt;/p&gt;

&lt;p&gt;When I showed it to Ved, he was stunned: &lt;em&gt;"Brochacho we're actually using this for our contest prep now."&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Below is the full demo of the project, you may have to wait good 2 sec for it to load!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhhppgy7a35jdjtzb17gm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhhppgy7a35jdjtzb17gm.gif" alt="cpmeta Full Project Demo" width="720" height="405"&gt;&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/prathamanvekar" rel="noopener noreferrer"&gt;
        prathamanvekar
      &lt;/a&gt; / &lt;a href="https://github.com/prathamanvekar/cpmeta" rel="noopener noreferrer"&gt;
        cpmeta
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Feeding your chaotic scratchpad notes to a local LLM so it can professionally diagnose your skill issues.
    &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;cpmeta 🧠&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;A thinking-process analyzer for competitive programmers. Takes raw, timestamped scratchpad notes from your practice sessions and turns them into actionable algorithmic insights, stall root causes, and targeted study plans using local LLMs.&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why cpmeta?&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;When solving LeetCode or Codeforces problems, developers often keep scratchpad notes:&lt;/p&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;0:00 - read problem statement. contiguous subarrays with k distinct elements.
0:03 - thought about standard sliding window with two pointers.
0:07 - stuck: how to count *exact* k without missing smaller left bounds?
0:15 - breakthrough: exact(k) = atMost(k) - atMost(k - 1)
0:22 - tested edge cases and submitted -&amp;gt; Accepted.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These notes capture your real-time cognitive blindspots, but usually get discarded. &lt;strong&gt;cpmeta&lt;/strong&gt; parses your notes alongside the problem statement with a local LLM to figure out:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Where and why you got stuck&lt;/strong&gt; (root cause analysis with exact durations).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Behavioral patterns&lt;/strong&gt; (e.g. abandoning correct approaches too early, missing invariants).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cumulative weaknesses&lt;/strong&gt;…&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/prathamanvekar/cpmeta" 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 engine is powered by &lt;strong&gt;Ollama&lt;/strong&gt; running open-weight coding models like &lt;code&gt;qwen2.5-coder:7b&lt;/code&gt; locally. It connects directly to the local Ollama instance on port 11434, while also supporting remote endpoints via Cloudflare tunnels or Ngrok when needed.&lt;/p&gt;

&lt;p&gt;To make local models output consistent coaching data instead of unstructured chat, we constrain inference to a &lt;strong&gt;strict JSON schema&lt;/strong&gt; and pair it with a multi-stage parser that heals trailing truncations:&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="c1"&gt;# Querying local Ollama with JSON enforcement and defensive extraction
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&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="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/api/generate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&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;model&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;model_name&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="n"&gt;SINGLE_PROBLEM_SYSTEM_PROMPT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stream&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;format&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;json&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;options&lt;/span&gt;&lt;span class="sh"&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;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;top_p&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;analysis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extract_clean_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&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="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The interface is built with &lt;strong&gt;Python and Streamlit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;All sessions, raw notes, and coach metrics persist in an embedded &lt;strong&gt;SQLite database&lt;/strong&gt; (&lt;code&gt;cpmeta.db&lt;/code&gt;). For longitudinal synthesis, a custom aggregator condenses weeks of practice history into high-signal JSON summaries that fit comfortably within local LLM context windows without blowing past token limits. To ensure stable UI rendering, a multi-stage parser sanitizes raw model responses and auto-recovers valid JSON schemas.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Competitive programmers solve hundreds of problems every month. Paying metered cloud API bills for every quick thought note or practice session is unrealistic for students and independent builders. Open-weight models running on consumer hardware &lt;strong&gt;cost nothing to run&lt;/strong&gt;, making deliberate practice truly unlimited.&lt;/p&gt;

&lt;p&gt;Problem-solving scratchpads are also raw, unfiltered mental dumps. Keeping inference &lt;strong&gt;entirely on-device&lt;/strong&gt; ensures that no personal notes, contest thoughts, or thinking habits ever leave the machine.&lt;/p&gt;

&lt;p&gt;Finally, practice happens anywhere - on commutes, in libraries with restrictive firewalls, or during offline study sprints. Because cpmeta relies on local Ollama inference, the entire diagnostic suite works seamlessly &lt;strong&gt;without internet access&lt;/strong&gt;, accounts, or third-party API dependencies.&lt;/p&gt;
&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;


&lt;div class="ltag-agent-session"&gt;
  &lt;div class="agent-session-header"&gt;
    
    &lt;span class="agent-session-tool-icon-badge" title="Gemini CLI"&gt;
&lt;/span&gt;
    &lt;span class="agent-session-title"&gt;Building cpmeta: Local AI Metacognition Engine for Competitive Programming&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;Build cpmeta: a Competitive Programming Metacognition Notes Analyzer using local Ollama LLMs, Streamlit, and SQLite.&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;Designed the Minimal Neobrutalist UI, implemented Ollama API client with defensive multi-stage JSON parsing, SQLite schema and session seeder, single-problem ICPC coach analysis, and cross-session longitudinal pattern synthesis.&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;Fix the card rendering issue where HTML tags were displaying as raw text inside divs, rename the project to cpmeta across all files, and create clean gitignore and documentation.&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;Identified CommonMark 4-space indentation bug where markdown engines treat indented HTML as code blocks. Implemented robust line-stripping render_html helper, refactored dynamic item templates, renamed all branding and database schema to cpmeta with automatic migration, and created production-ready .gitignore and minimal README.&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;
        4 of 4 messages
    &lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;



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

&lt;p&gt;Render&lt;/p&gt;

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