This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass
#
What I Built
AI Gardener β Spend 30 seconds here. Spend the rest outside.
Most gardening apps and AI chatbots do the exact opposite of touching grass: they keep you glued to your screen reading long encyclopedias, tweaking complex trackers, or scrolling through walls of generic AI text. I built AI Gardener around a single rule: spend 30 seconds on the screen to see today's exact physical action, then close the app and go outside into your garden.
AI Gardener is an open-source, multimodal gardening companion powered by local open-weight models (gemma3:4b for structured reasoning and vision, and nomic-embed-text for 768-dimensional semantic embeddings via Ollama), grounded with MongoDB Atlas Vector Search, and deployed live on Render.
Instead of giving generic textbook advice, AI Gardener acts like a local agronomist that remembers your garden across days and weeks:
Go Outside β Today's Next Actions Card: At the very top of the dashboard, a dedicated action card surfaces the single next physical task for each of your active gardens (up to 3 concurrent gardens per user). You check what to do today in 30 seconds, walk outside, do the work in the soil, and mark it Done. #
Sequential Multi-Day Lifecycle Progression: Tasks are completed in real-world chronological order (Day 1 ,Day 2 ,Day 3 ...). Once you finish your current batch of 5 tasks, aDone β Generate Next Plan button unlocks, advancing your garden fromDay 1β5 toDay 6β10 and transitioning your garden phase fromPLANTING toGROWING andMAINTENANCE without ever repeating completed tasks. #
Hyper-Local Climate and Crop Grounding: Growing tomatoes in Gorakhpur during winter fog (Rabi season) requires completely different care than growing hibiscus in Shimla or okra in Pune during the monsoon. I grounded the system in 2,174 curated plant health records across 76 crops and 70 agro-climatic records sourced from ICAR-CRIDA district contingency plans and meteorological authorities. #
Multimodal Leaf Photo Diagnosis: When you are outside in your garden and notice yellow halos, leaf curl, or brown spots on a leaf, you snap a photo and upload it. Gemma 3's vision capability inspects the leaf, cross-checks our plant pathology and local climate vectors (such as morning fog increasing fungal blight risk), and automatically updates your daily task schedule with targeted recovery actions.
Who is it for?
Home gardeners, balcony and terrace growers, and beginners who want hyper-local, step-by-step physical tasks tailored to their exact city, square footage or pot count, daily sunlight hours, and season.
#
Demo
#
Code
β¨ The Idea #
Most AI tools keep you glued to a screen.
AI Gardener flips that.
You spend 30 seconds telling it about your garden. It gives you one clear task for today. You go outside, do it, come back, and optionally snap a photo of your plant. The AI analyzes the photo, checks its knowledge base for diseases or care tips, and gives you tomorrow's task.
The screen is the shortest part of the experience.
π― Prize Categories #
| Category | How We Qualify |
| π Overall (Touch Grass) | Spend 30 seconds on the screen, spend the rest outside β built on open-weight gemma3:4b andnomic-embed-text |
| π MongoDB Atlas | 4 collections ( garden_sessions ,users ,plant_health_knowledge with 2,174 records,climate_location_knowledge with 70 records) + 768-dim |
β¦
GitHub Repository: https://github.com/the-curious-lad/ai-gardener
#
How I Built It
I built AI Gardener around a modular, provider-agnostic open-source AI architecture running gemma3:4b and nomic-embed-text locally on Ollama, backed by MongoDB Atlas for stateful session persistence and 768-dimensional vector retrieval, and hosted on Render.
- Four-Stage Agentic Pipeline
Every user message or photo upload flows through four specialized stages:
Stage 1 β Intent-Aware Query Rewriter and Router (queryRewriter.js): Combines gemma3:4b structured JSON extraction (validated with Zod schemas) with a deterministic regex signal extractor so explicit user inputs (cities, Indian states, sq ft/pots, sunlight hours, seasons, and plant names) are never dropped or re-asked. Initial garden planning requires all 5 essential context fields (plant, city/state, growing area, daily sunlight hours, and season), while general botany questions or photo observations bypass unnecessary context checks. #
Stage 2 β Dual-Collection Hybrid Vector Retrieval (knowledgeVectorSearch.js and climateVectorSearch.js): Converts the normalized query into a 768-dimensional vector usingnomic-embed-text and queries two MongoDB Atlas collections in parallel:plant_health_knowledge (2,174 records across 76 crops) andclimate_location_knowledge (70 district and agro-climatic zone records). For regional climate, it resolves a 4-tier geographic hierarchy: Exact Location Mapping -> Regional Climate -> Seasonal Context -> Country/Zone Fallback. #
Stage 3 β Multimodal Photo Reader (photoReader.js): Uses gemma3:4b vision to extract structured symptoms (visibleSymptoms ,leafCondition ,possiblePestSigns ,possibleDiseaseSigns ,severity , andconfidence ) from uploaded leaf photos, feeding those visual findings directly into the vector search and planner. #
Stage 4 β Phase-Aware Planner (plannerService.js): Synthesizes user context, retrieved agronomic records, climate constraints, and completed task history to generate sequential daily tasks (Day 1 toDay 5 , thenDay 6 toDay 10 , etc.) and manage lifecycle transitions (PLANTING ->GROWING ->MAINTENANCE ).
- Multi-Layer Domain and Input Guardrails
Small 4B parameter models can easily get derailed if a user enters impossible physical numbers, fictional places, or prompt injections. I built 5 deterministic guardrail layers around the Query Rewriter and Planner:
Guardrail 1 β Off-Topic, Length, and Prompt-Injection Fast-Path (0 LLM Calls): Non-gardening queries (coding, sports, finance, cooking recipes), messages exceeding the 600-character limit, and prompt-injection attempts (such as "ignore previous instructions" or "reveal system prompt") are intercepted and refused in under 1 millisecond with zero LLM calls. #
Guardrail 2 β Physical Sunlight Bounds Validation (1 to 16 Hours): If someone enters an impossible value like 100 hours of daily sunlight or 0 hours, the guardrail rejects the invalid number while preserving the rest of their valid context, reminding them that a day only has 24 hours and asking for a realistic 1 to 16 hour daily sunlight figure. #
Guardrail 3 β Knowledge-Base Location Verification: If a user enters an unrecognized or fictional place (like "Atlantis") that is not in our climate knowledge base, the system strips the invalid location and transparently asks the user for a supported city or Indian state instead of hallucinating climate data. #
Guardrail 4 β Supported Plant Verification: Every requested plant is checked against our 76 verified CSV crops and supported Indian garden/ornamental plants. If someone asks to grow a non-plant item or unsupported species, the guardrail catches it immediately and suggests supported vegetables, herbs, fruits, and flowers. #
Guardrail 5 β Agronomic Low-Sunlight Mismatch Warnings: When a user plans a sun-loving crop (such as tomato, sunflower, chilli, hibiscus, or rose) with less than 4 hours of daily sunlight, the Planner automatically prepends a Sunlight Heads-Up warning advising them to place movable containers in their brightest south- or west-facing spot.
- Bounded Context Summarizer for Small Local Models
Feeding an ever-growing chat history into a local 4B model quickly degrades instruction following and increases latency. I built a deterministic Context Summarizer (contextSummarizer.js) that maintains a compact 7-line structured memory summary (contextSummary) inside MongoDB while preserving the full raw conversationHistory in the database. Every AI prompt receives only the compact summary plus the last 4 messages, keeping token counts flat and inference fast even after dozens of turns.
- Engineering for Latency, Streaming Resilience, and a 371 MB -> 114 MB Memory Optimization
Running an AI + Vector Search backend on Render's 512 MB RAM tier alongside a tunneled local Ollama instance surfaced real production challenges that I solved during development:
Cutting Memory Usage from 371 MB to 114 MB (69% Reduction): Initially, Render was crashing with HTTP 502 Out-Of-Memory errors. Profiling heap memory revealed that parsing our 9.2 MBplant_health_knowledge.csv fallback file character-by-character (currentField += ch ) created millions of V8ConsString sliced string references, ballooning heap + RSS memory to 371 MB. I rewroteparseCSV insrc/utils/csvParser.js using zero-copy index slicing (content.slice(fieldStart, i) ) and flat UTF-8 buffer allocation, dropping CSV memory footprint from 371 MB down to 114 MB. #
Progressive Filter Relaxation in Vector Search: Instead of all 2,174 documents into Node.js memory when a strict metadata filter returned 0 hits, I implemented progressive filter relaxation directly in MongoDB (plant + knowledgeTypes ->plant only -> bounded 200-document slice), keeping steady-state vector search RAM at just 63 MB. #
Streaming NDJSON + Truncated JSON Auto-Repair: Whengemma3:4b generated long 5-day plans over a tunnel, waiting for a single non-streamed HTTP response caused proxy idle timeouts. I switchedOllamaProvider to stream NDJSON tokens continuously (stream: true ), added automatic brace/quote stack balancing (repairJsonCandidate ) to recover truncated JSON outputs, and added a 24/7 hybrid deterministic fallback so the live Render app stays 100% functional even when my local laptop GPU is offline.
#
Why Does Open Innovation Matter?
Building AI Gardener on open-weight models (gemma3:4b and nomic-embed-text) via Ollama proved four major advantages over closed proprietary APIs:
True Multimodal Privacy for Home Photos: When users take photos of their backyard, balcony, or living space to diagnose a plant leaf, those images are processed on open weights under my control rather than being uploaded to a commercial third-party training pipeline.
2.
Zero Per-Token Cost for Multi-Step Agent Loops: Each garden plan or photo diagnosis runs multiple structured steps (Query Rewriter -> 768-dim Embedding -> Dual Vector Retrieval -> Multimodal Vision -> Phase Planner). With open weights running locally on Ollama, iterating across hundreds of test turns and multi-day replans cost $0.00 in API fees.
3.
Deterministic Control Over Small Models: Because I could inspect every raw token stream fromgemma3:4b , I was able to build custom JSON stream repair, bounded 7-line context summarization, and domain guardrails that make a compact 4B open model perform reliably on consumer hardware.
4.
Hybrid Edge + Cloud Resilience: By combining a cloud web host (Render) and cloud vector database (MongoDB Atlas) with a tunneled local Ollama inference engine and deterministic agronomy fallbacks, the project demonstrates how solo developers can ship zero-cost, open-weight AI web apps to production.
#
My Agent Session
During my agentic pair-programming session in Google Antigravity, AI Gardener evolved from a basic single-session chat prototype into a hardened, production-grade multi-garden platform. Here is a summary of what our initial prototype looked like and the key engineering changes we made together:
From Single Chat Prototype to Multi-Garden Lifecycle Management: We started with a single-session chat prototype, then redesigned the architecture to support lightweight user accounts, up to 3 concurrent gardens per user, a unified "GO OUTSIDE β TODAY'S NEXT ACTIONS" card across all active gardens, and strict sequential task completion (Day 1β5 ->Done β Generate Next Plan ->Day 6β10 ).
2.
Solving the Day 6+ Replan & Phase Regression Bug: When testing multi-week progression, we noticedgemma3:4b sometimes repeatedDay 6 labels or reset the phase back toPLANTING on Day 6. We re-engineered the Planner prompt and deterministic post-processor to filter out completed task titles, enforce monotonic day numbering (startDay + idx ), and advance phases cleanly fromPLANTING ->GROWING ->MAINTENANCE .
3.
Debugging Render's 512 MB OOM Crash (371 MB -> 114 MB): When deploying to Render, the server hit HTTP 502 Out-Of-Memory restarts. We profiled Node.jsprocess.memoryUsage() step-by-step, discovered that character-by-character CSV parsing on the 9.2 MB knowledge base was allocating 371 MB of V8ConsString objects, and rewrote the parser with zero-copy slicing to bring memory down to 114 MB (and 63 MB steady-state during vector search).
4.
Fixing Proxy Timeouts with NDJSON Streaming & JSON Repair: Long structured outputs from localgemma3:4b over a Cloudflare tunnel occasionally timed out or truncated mid-JSON. We switchedOllamaProvider to continuous NDJSON streaming, built a stack-based JSON auto-repair utility (repairJsonCandidate ), and added a clean one-clickRetry Sending button in the UI.
5.
Hardening Security & Adding 5 Domain Guardrails: In our final pass, we removed the internal Pipeline Inspector from the client UI so raw server state is never exposed, added a 600-character input cap, and built 5 domain guardrails so unrealistic inputs (like "100 hours of sunlight" or unknown cities/plants) are caught and explained gracefully.
#
Prize Categories
Overall Challenge Winner β Week 1: Touch Grass (Open-Source AI Innovation): Built from the ground up with open-weight models (gemma3:4b andnomic-embed-text via Ollama) around the core motto "Spend 30 seconds here. Spend the rest outside." β turning local agro-climatic data, 2,174 plant pathology records, and leaf photos into immediate daily physical tasks in the garden. #
Best Use of Gemma: Usesgemma3:4b as both its structured JSON reasoning router/planner and its multimodal vision engine for leaf disease diagnosis, enhanced with custom JSON stream repair, 5 domain guardrails, and a bounded 7-line context summarizer designed specifically for a 4B parameter context window. #
Best Use of Render: Deployed live on Render (https://ai-gardener.onrender.com ) and engineered specifically for Render's 512 MB RAM environment by reducing CSV parser memory from 371 MB to 114 MB, streaming NDJSON chunks to prevent proxy timeouts, and providing a 24/7 hybrid fallback. #
Best Use of MongoDB Atlas: Uses MongoDB Atlas across 4 collections (garden_sessions ,users ,plant_health_knowledge , andclimate_location_knowledge ), combining stateful multi-garden lifecycle persistence with 768-dimensional$vectorSearch retrieval across 2,174 plant health records and 70 hierarchical climate records.
Thank you to the DEV team, MLH, DigitalOcean, Google DeepMind, Render, and MongoDB for hosting Hacktoberfest 2026 and championing open-source AI! Building this project solo was an awesome learning experience β now it is time for me to close my terminal, step outside, and touch some grass. π±