# 🌴 Palm Oil Ripeness Agent (n8n + YOLOv8)

This project uses a custom-trained **YOLOv8** model to detect the ripeness of Palm Oil Fresh Fruit Bunches (FFB). It features a local Python FastAPI server and a Streamlit Dashboard, both architected with **Domain-Driven Design (DDD)** for maximum flexibility and scalability in an **agentic n8n workflow**.

## 🚀 Project Overview

1.  **Vision Engine:** YOLOv8 Nano (Custom-trained on MPOB-standard datasets).
2.  **Inference Server:** FastAPI (Python) for n8n integration.
3.  **Visual Fingerprinting:** Vertex AI Multimodal Embedding (`multimodalembedding@001`).
4.  **Archival & Reasoning:** MongoDB Atlas Vector Search for similarity-based reasoning.
5.  **Demo Dashboard:** Streamlit UI for drag-and-drop batch testing.

---

## 🛠 Prerequisites

-   Python 3.10+
-   n8n (Desktop or Self-hosted)
-   MongoDB Atlas Account
-   Google Cloud Platform (Vertex AI API enabled)

---

## 📦 Setup Instructions

### 1. Environment Setup

```powershell
# Clone and enter the repository
git clone <your-repo-url>
cd palm-oil-ai

# Create and activate virtual environment
python -m venv venv
.\venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt
```

### 2. Dataset & Training

1. Download the dataset from [Roboflow](https://universe.roboflow.com/assignment-vvtq7/oil-palm-ripeness/dataset/5/download/yolov8)
*Or you can also find your own separate source of datasets. Make sure the file/folder format structure is consistent, especially the .yaml file.
2. Extract into `/datasets`.
3. **Train the model:**
```bash
python train_script.py

```

3. Copy the resulting `best.pt` from `runs/detect/train/weights/` to the project root.

### 3. Configuration (`.env`)

Ensure your `.env` file is populated with the following keys:
- `MONGO_URI`: Your MongoDB Atlas connection string.
- `PROJECT_ID`: Your Google Cloud Project ID.
- `LOCATION`: Vertex AI location (e.g., `us-central1`).
- `DB_NAME`: MongoDB database name.
- `COLLECTION_NAME`: MongoDB collection name.
- `GOOGLE_APPLICATION_CREDENTIALS`: Path to your GCP service account JSON key.

---

## 🚦 How to Run
### Running the API Server

The API acts as the bridge for n8n or mobile integrations. You can start it using the root wrapper:

```powershell
# Start the FastAPI server
python main.py
```
*Alternatively, run as a module: `python -m src.api.main`*

### Running the Streamlit Dashboard

For manual testing and visual analysis:

```powershell
# Start the Streamlit app
streamlit run demo_app.py
```

---

## 🔌 API Endpoints

| Endpoint | Method | Description |
| :--- | :--- | :--- |
| `/analyze` | `POST` | **Local Detection**: Returns YOLO results only. Guaranteed to work without Cloud Billing. |
| `/vectorize_and_store` | `POST` | **Cloud Archival**: Vectorizes a detection and saves to MongoDB Atlas. Requires GCP Billing. |
| `/process_batch` | `POST` | **Bulk Processor**: Handles multiple images. Detects locally; archives to cloud if available. |
| `/search_hybrid` | `POST` | **Semantic Search**: Visual similarity or natural language search via Vertex AI. |
| `/get_confidence` | `GET` | Retrieve the current AI confidence threshold. |
| `/set_confidence` | `POST` | Update the AI confidence threshold globally. |

---

## 📂 Repository Structure (DDD)

```text
├── src/
│   ├── api/                # FastAPI entry points & route handlers
│   ├── application/        # Use Cases & Orchestration logic
│   ├── domain/             # Business Logic, Entities, & Core models
│   └── infrastructure/     # External integrations (MongoDB, VertexAI)
├── datasets/               # Labeled images (Train/Valid/Test)
├── runs/                   # YOLO training logs and output weights
├── best.pt                 # THE BRAIN: Trained model weights
├── requirements.txt        # Python dependencies
├── .env                    # Configuration state
├── LICENSE                 # MIT License
└── README.md               # You are here
```

## 📜 License

This project is licensed under the MIT License - see the [LICENSE](file:///LICENSE) file for details.
