Hacktoberfest 2026 Β· Week 1
An open-source AI gardening assistant that gets you off the screen and into the soil.
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.
| 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.
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
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 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 β
βββββββββββββββββββββββββββββββββ
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 |
- One backend, no microservices. All logical components are clean internal modules.
- One knowledge collection.
plant_health_knowledgecovers everything β planting, disease, nutrition, maintenance β categorised byknowledge_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.
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/
| Tool | Version | Notes |
|---|---|---|
| Node.js | 20+ | β |
| npm | 9+ | β |
| Ollama | latest | Install |
| MongoDB Atlas | β | Free tier works |
git clone https://github.com/your-username/ai-gardener.git
cd ai-gardener
npm install# 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- Create a free cluster at mongodb.com/atlas.
- Create two databases:
garden_appandgardening_knowledge. - Copy your connection string.
- Create one Vector Search index on
plant_health_knowledge(see below).
cp .env.example .env
# Edit .env with your MongoDB URI and settingsMONGODB_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=3000node scripts/seed.jsThis 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.
npm start
# Server running at http://localhost:3000Create 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.
| 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 |
# 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"
}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": [...]
}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.
This project was built for Hacktoberfest 2026. All contributions welcome!
- Fork the repo
- Create a branch:
git checkout -b feature/your-feature - Commit your changes:
git commit -m 'Add some feature' - Push to the branch:
git push origin feature/your-feature - Open a Pull Request
- Add more plant records to
data/seed_knowledge.json(useknowledge_type: "PLANT_BASIC") - Add more disease records to
data/seed_knowledge.json(useknowledge_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/
MIT Β© 2026 β Built with π± for Hacktoberfest
Go touch grass. The AI will keep track of everything else.