Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

🌱 AI Gardener β€” Touch Grass

Hacktoberfest 2026 Β· Week 1

An open-source AI gardening assistant that gets you off the screen and into the soil.

Node.js MongoDB Atlas Gemma 3 Ollama Render License: MIT Hacktoberfest


✨ 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 and nomic-embed-text
πŸƒ MongoDB Atlas 4 collections (garden_sessions, users, plant_health_knowledge with 2,174 records, climate_location_knowledge with 70 records) + 768-dim Atlas Vector Search
πŸ€– Gemma Gemma 3 4B (via Ollama) for structured JSON routing/planning and multimodal leaf photo diagnosis
☁️ Render Deployed live at https://ai-gardener.onrender.com with 512 MB RAM optimization (371 MB -> 114 MB) & NDJSON streaming

Every technology in this stack has a genuine functional role β€” nothing was added for prize hunting.


πŸ”„ How It Works

You tell it about your garden
        ↓
AI asks only what it needs to know
        ↓
Retrieves relevant plant knowledge (Vector Search)
        ↓
Builds your personalised X-day plan
        ↓
You go outside and complete a task ← THE WHOLE POINT
        ↓
You snap a photo of your plant
        ↓
Gemma 3 analyses the image β†’ structured observation
        ↓
AI searches plant_health_knowledge (DISEASE Β· PEST Β· NUTRIENT_DEFICIENCY types)
        ↓
Planner updates your garden state & next tasks
        ↓
Repeat

🧠 Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Express API Layer                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚   Query Rewriter &      β”‚
              β”‚   Context Manager       β”‚  ← Heart of the system
              β””β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚          β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”   β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
        β”‚  Photo   β”‚   β”‚  Planner   β”‚  ← Phase-aware decision maker
        β”‚  Reader  β”‚   β”‚  Executor  β”‚
        β”‚(Gemma 3) β”‚   β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
        β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜        β”‚
             β”‚         β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        Observation    β”‚   MongoDB Atlas                β”‚
             β”‚         β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
             └────────►│  β”‚  Vector Search           β”‚ β”‚
                        β”‚  β”‚  plant_health_knowledge  β”‚ β”‚
                        β”‚  β”‚  (knowledge_type filter) β”‚ β”‚
                        β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
                        β”‚  garden_sessions               β”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Knowledge Types

One collection. One index. The Query Rewriter selects which knowledge_type values to retrieve:

Query knowledge_type filters used
"How should I grow tomatoes?" PLANT_BASIC, PLANTING, SOIL, WATER, SUNLIGHT, CLIMATE
Photo of yellowing leaves DISEASE, PEST, NUTRIENT_DEFICIENCY, ENVIRONMENTAL_STRESS, HEALTHY_BASELINE
"What should I do today?" MAINTENANCE, GROWTH_STAGE, PREVENTION
"Does my plant look healthy?" HEALTHY_BASELINE, GROWTH_STAGE

Key Design Principles

  • One backend, no microservices. All logical components are clean internal modules.
  • One knowledge collection. plant_health_knowledge covers everything β€” planting, disease, nutrition, maintenance β€” categorised by knowledge_type, not split into separate tables.
  • Vision is observational only. A photo never directly mutates the database. It produces an observation β†’ Planner evaluates β†’ state updates.
  • Minimum sufficient context. The Query Rewriter collects only what it needs, never re-asks what it knows.
  • Modular AI layer. Swap Gemma 3 / Ollama for any other model without touching application logic.
  • Validated LLM outputs. Every structured AI response is validated with Zod before any database write.

πŸ—‚οΈ Project Structure

ai-gardener/
β”œβ”€β”€ data/
β”‚   β”œβ”€β”€ plant_health_knowledge.csv     # 2,175 extension-verified records across 17 knowledge_types
β”‚   └── plant_health_source_audit.csv  # 2,470 source verification & citation audit records
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ seed.js                  # Ingest CSV knowledge + generate embeddings
β”‚   β”œβ”€β”€ demo-path-1.js           # Demo: clarification β†’ plan
β”‚   └── demo-path-2.js           # Demo: photo β†’ knowledge search β†’ replan
β”œβ”€β”€ public/                      # Minimal frontend (Vanilla JS)
β”‚   β”œβ”€β”€ index.html
β”‚   β”œβ”€β”€ styles.css
β”‚   └── app.js
└── src/
    β”œβ”€β”€ config/                  # Env + DB connection
    β”œβ”€β”€ models/                  # Zod schemas + Mongoose models
    β”œβ”€β”€ prompts/                 # Versioned LLM prompts
    β”œβ”€β”€ repositories/            # All DB operations
    β”œβ”€β”€ services/
    β”‚   β”œβ”€β”€ ai/                  # AIProvider β†’ OllamaProvider (Gemma 3)
    β”‚   β”œβ”€β”€ embeddings/          # EmbeddingProvider β†’ OllamaEmbeddingProvider
    β”‚   β”œβ”€β”€ vectorSearch/        # knowledgeVectorSearch (knowledge_type filtered)
    β”‚   β”œβ”€β”€ context/             # Query Rewriter & clarification loop
    β”‚   β”œβ”€β”€ photo/               # Photo Reader (Gemma 3 multimodal)
    β”‚   β”œβ”€β”€ planner/             # Phase-aware Planner
    β”‚   └── orchestrator/        # KNOWβ†’PLANβ†’ACTβ†’OBSERVEβ†’UPDATE loop
    β”œβ”€β”€ controllers/
    β”œβ”€β”€ routes/
    └── utils/

πŸš€ Quick Start

Prerequisites

Tool Version Notes
Node.js 20+ β€”
npm 9+ β€”
Ollama latest Install
MongoDB Atlas β€” Free tier works

1 Β· Clone & Install

git clone https://github.com/your-username/ai-gardener.git
cd ai-gardener
npm install

2 Β· Set Up Ollama

# Install Ollama (if not installed)
# https://ollama.com/download

# Pull the models
ollama pull gemma3:4b
ollama pull nomic-embed-text

# Verify Ollama is running
ollama list

3 Β· Set Up MongoDB Atlas

  1. Create a free cluster at mongodb.com/atlas.
  2. Create two databases: garden_app and gardening_knowledge.
  3. Copy your connection string.
  4. Create one Vector Search index on plant_health_knowledge (see below).

4 Β· Configure Environment

cp .env.example .env
# Edit .env with your MongoDB URI and settings
MONGODB_URI=mongodb+srv://user:pass@cluster.mongodb.net/
MONGODB_APP_DB=garden_app
MONGODB_KNOWLEDGE_DB=gardening_knowledge
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=gemma3:4b
EMBEDDING_MODEL=nomic-embed-text
EMBEDDING_DIMENSIONS=768
PORT=3000

5 Β· Seed Knowledge Base

node scripts/seed.js

This ingests all plant health knowledge (plant basics, diseases, pests, nutrition, etc.) from data/seed_knowledge.json into MongoDB, generates embeddings via Ollama, and prepares the Vector Search documents.

6 Β· Start the Server

npm start
# Server running at http://localhost:3000

πŸ” MongoDB Atlas Vector Search Setup

Create this index in the Atlas UI under Search β†’ Create Index β†’ JSON Editor.

Database: gardening_knowledge Β· Collection: plant_health_knowledge Index name: plant_health_knowledge_vector_index

{
  "fields": [
    {
      "type": "vector",
      "path": "embedding",
      "numDimensions": 768,
      "similarity": "cosine"
    },
    { "type": "filter", "path": "plant" },
    { "type": "filter", "path": "knowledge_type" },
    { "type": "filter", "path": "tags" }
  ]
}

The knowledge_type filter lets the Query Rewriter scope retrieval precisely β€” for example, a photo observation query passes knowledge_type: { $in: ["DISEASE", "PEST", "NUTRIENT_DEFICIENCY", "HEALTHY_BASELINE"] } as a pre-filter, so only relevant records are scored by the vector model.

Note: The vector search service includes an automatic in-memory cosine similarity fallback while the Atlas index is building, so local development never breaks.


πŸ“‘ API Reference

Method Endpoint Description
POST /api/sessions Create a new garden session
GET /api/sessions/:id Get session state & garden context
POST /api/sessions/:id/message Send a chat message
POST /api/sessions/:id/photo Upload a plant photo for analysis
GET /api/sessions/:id/tasks List all tasks
POST /api/tasks/:taskId/complete Mark a task complete & trigger replan

Example: Start a Garden

# Create session
curl -X POST http://localhost:3000/api/sessions \
  -H "Content-Type: application/json" \
  -d '{"userId": "user_1"}'

# Send first message (triggers clarification loop)
curl -X POST http://localhost:3000/api/sessions/SESSION_ID/message \
  -H "Content-Type: application/json" \
  -d '{"message": "I have some land in Gorakhpur and want to grow tomatoes"}'
{
  "reply": "Great! How large is your growing area, and approximately how many hours of direct sunlight does it receive each day?",
  "status": "NEEDS_CONTEXT"
}

Example: Upload a Photo

curl -X POST http://localhost:3000/api/sessions/SESSION_ID/photo \
  -F "photo=@tomato_leaf.jpg" \
  -F "message=My tomato leaves look strange"
{
  "observation": {
    "plantDetected": "tomato",
    "visibleSymptoms": ["yellowing lower leaves", "brown circular spots"],
    "possibleDiseaseSigns": ["fungal-like leaf spotting"],
    "severity": "moderate",
    "confidence": 0.71,
    "uncertainties": ["Image resolution limits certainty"]
  },
  "recommendation": "The observation suggests possible early blight. I've retrieved the relevant care guidance and updated your tasks.",
  "updatedTasks": [...]
}

πŸͺ΄ Gardening Phases

The system guides you through three phases automatically:

Phase Focus
🌱 PLANTING Choosing plants, soil prep, spacing, initial watering
🌿 GROWING Growth monitoring, health checks, growth-stage tracking
βœ‚οΈ MAINTENANCE Irrigation, pruning, fertilisation, disease prevention

Phase transitions are decided by the Planner using observations + plant timelines + retrieved knowledge β€” never triggered directly by a photo.


🀝 Contributing

This project was built for Hacktoberfest 2026. All contributions welcome!

  1. Fork the repo
  2. Create a branch: git checkout -b feature/your-feature
  3. Commit your changes: git commit -m 'Add some feature'
  4. Push to the branch: git push origin feature/your-feature
  5. Open a Pull Request

Good First Issues

  • Add more plant records to data/seed_knowledge.json (use knowledge_type: "PLANT_BASIC")
  • Add more disease records to data/seed_knowledge.json (use knowledge_type: "DISEASE")
  • Add pest, nutrition, or maintenance knowledge records
  • Improve prompt quality in src/prompts/
  • Add unit tests for the Query Rewriter
  • Improve UI in public/

πŸ“„ License

MIT Β© 2026 β€” Built with 🌱 for Hacktoberfest


Go touch grass. The AI will keep track of everything else.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages