Spaces:
Sleeping
Sleeping
Commit
Β·
f24b4d8
1
Parent(s):
e4f78d3
base
Browse files- agent_setup.py +46 -0
- app.py +26 -119
- app2.py +0 -247
- config.py +13 -0
- knowledge_base.md +20 -0
- knowledge_base.py +36 -0
- vision_model.py +26 -0
agent_setup.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from google.adk import Agent, Runner
|
| 2 |
+
from google.adk.sessions import InMemorySessionService
|
| 3 |
+
from tools import create_plant_diagnosis_tool, create_remedy_retrieval_tool
|
| 4 |
+
|
| 5 |
+
def initialize_adk(vision_model, processor, retriever):
|
| 6 |
+
"""
|
| 7 |
+
Initializes the ADK agent, tools, and runner.
|
| 8 |
+
|
| 9 |
+
Args:
|
| 10 |
+
vision_model: The loaded vision model.
|
| 11 |
+
processor: The model's processor.
|
| 12 |
+
retriever: The RAG retriever.
|
| 13 |
+
|
| 14 |
+
Returns:
|
| 15 |
+
A dictionary containing the ADK components, or None on error.
|
| 16 |
+
"""
|
| 17 |
+
print("Initializing ADK Tools and Agent...")
|
| 18 |
+
try:
|
| 19 |
+
if vision_model and processor and retriever:
|
| 20 |
+
diagnosis_tool = create_plant_diagnosis_tool(model=vision_model, processor=processor)
|
| 21 |
+
remedy_tool = create_remedy_retrieval_tool(retriever=retriever)
|
| 22 |
+
|
| 23 |
+
agent = Agent(
|
| 24 |
+
name="AuraMindGlowAgent",
|
| 25 |
+
model="gemini-2.5-flash",
|
| 26 |
+
description="A farming assistant that can diagnose plant health and suggest remedies.",
|
| 27 |
+
instruction="You are a friendly farming assistant. Your goal is to help users identify plant health issues and find solutions. Use your tools to diagnose the plant from an image and then find a remedy.",
|
| 28 |
+
tools=[diagnosis_tool, remedy_tool]
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
session_service = InMemorySessionService()
|
| 32 |
+
runner = Runner(agent=agent, app_name="AuraMindGlow", session_service=session_service)
|
| 33 |
+
|
| 34 |
+
print("β
ADK Agent and Runner initialized successfully!")
|
| 35 |
+
return {
|
| 36 |
+
"agent": agent,
|
| 37 |
+
"runner": runner,
|
| 38 |
+
"diagnosis_tool": diagnosis_tool,
|
| 39 |
+
"remedy_tool": remedy_tool
|
| 40 |
+
}
|
| 41 |
+
else:
|
| 42 |
+
print("β Skipping ADK setup due to errors in model or RAG loading.")
|
| 43 |
+
return None
|
| 44 |
+
except Exception as e:
|
| 45 |
+
print(f"β CRITICAL ERROR during ADK setup: {e}")
|
| 46 |
+
return None
|
app.py
CHANGED
|
@@ -1,150 +1,54 @@
|
|
| 1 |
# ==============================================================================
|
| 2 |
-
# Aura Mind Glow - Main Application
|
| 3 |
# ==============================================================================
|
| 4 |
"""
|
| 5 |
This script launches the Aura Mind Glow application.
|
| 6 |
-
It features two modes:
|
| 7 |
-
1. Field Mode (100% Offline): For quick diagnosis and remedy retrieval.
|
| 8 |
-
2. Connected Mode (Online): A conversational agent powered by the Google ADK.
|
| 9 |
"""
|
| 10 |
|
| 11 |
# --- Step 0: Essential Imports ---
|
| 12 |
import gradio as gr
|
| 13 |
-
import torch
|
| 14 |
from PIL import Image
|
| 15 |
import os
|
| 16 |
import warnings
|
| 17 |
import socket
|
| 18 |
-
import asyncio
|
| 19 |
import tempfile
|
| 20 |
|
| 21 |
# Suppress potential warnings for a cleaner console
|
| 22 |
warnings.filterwarnings("ignore")
|
| 23 |
-
os.environ["TORCH_COMPILE_DISABLE"] = "1"
|
| 24 |
|
| 25 |
-
#
|
| 26 |
-
from
|
| 27 |
-
from
|
| 28 |
-
|
| 29 |
-
# LangChain and RAG components
|
| 30 |
-
from langchain_community.vectorstores import FAISS
|
| 31 |
-
from langchain_community.document_loaders import TextLoader
|
| 32 |
-
from langchain_huggingface import HuggingFaceEmbeddings
|
| 33 |
-
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
| 34 |
-
|
| 35 |
-
# Google ADK
|
| 36 |
-
from google.adk import Agent, Runner
|
| 37 |
-
from google.adk.sessions import InMemorySessionService
|
| 38 |
-
from google.genai import types
|
| 39 |
-
|
| 40 |
-
# Custom Tools
|
| 41 |
-
from tools import create_plant_diagnosis_tool, create_remedy_retrieval_tool
|
| 42 |
|
| 43 |
print("β
All libraries imported successfully.")
|
| 44 |
|
| 45 |
-
# --- Step
|
| 46 |
# This expensive setup runs only ONCE when the application starts.
|
| 47 |
|
| 48 |
-
print("Performing initial setup
|
| 49 |
-
VISION_MODEL =
|
| 50 |
-
|
| 51 |
-
RETRIEVER = None
|
| 52 |
-
ADAPTER_PATH = "surfiniaburger/maize-health-diagnosis-adapter"
|
| 53 |
-
|
| 54 |
-
try:
|
| 55 |
-
# Load Vision Model
|
| 56 |
-
VISION_MODEL, PROCESSOR = FastVisionModel.from_pretrained(
|
| 57 |
-
model_name="unsloth/gemma-3n-E2B-it-unsloth-bnb-4bit",
|
| 58 |
-
max_seq_length=2048,
|
| 59 |
-
load_in_4bit=True,
|
| 60 |
-
dtype=None,
|
| 61 |
-
)
|
| 62 |
-
FastVisionModel.for_inference(VISION_MODEL)
|
| 63 |
-
VISION_MODEL.load_adapter(ADAPTER_PATH)
|
| 64 |
-
print(f"β
Vision model and adapter '{ADAPTER_PATH}' loaded successfully!")
|
| 65 |
-
|
| 66 |
-
# Build RAG Knowledge Base
|
| 67 |
-
remedy_knowledge_text = """
|
| 68 |
-
# Maize Health Guide
|
| 69 |
-
## Phosphorus Deficiency
|
| 70 |
-
**Symptoms:** Plants are often stunted, dark green or purplish. This condition is sometimes called Purple leaf disease. The purplish discoloration is most evident on the tips of leaves of young plants.
|
| 71 |
-
**Cause:** Lack of available phosphorus in the soil, often due to incorrect pH or cold soil temperatures.
|
| 72 |
-
**Local Remedy:** Apply a high-phosphorus starter fertilizer at planting time. In organic systems, bone meal or rock phosphate are excellent sources. A foliar spray of a water-soluable phosphate fertilizer can be applied directly to the leaves for a quick, short-term fix. Ensure soil pH is between 6.0 and 7.0 for optimal phosphorus uptake.
|
| 73 |
-
## Nitrogen Deficiency
|
| 74 |
-
**Symptoms:** General yellowing (chlorosis) of the plant, starting with the lower, older leaves in a distinct "V" shape that progresses up the midrib.
|
| 75 |
-
**Cause:** Insufficient nitrogen in the soil, which is a mobile nutrient.
|
| 76 |
-
**Local Remedy:** Side-dress with a nitrogen-rich fertilizer like urea, ammonium nitrate, or composted manure whenplants are about knee-high. For organic farming, blood meal or feather meal are effective sources.
|
| 77 |
-
## Leaf Spot
|
| 78 |
-
**Symptoms:** Small, circular to oval spots with tan centers and dark borders on the leaves. This is a common fungal disease.
|
| 79 |
-
**Cause:** Fungal pathogens that spread via water splash and wind.
|
| 80 |
-
**Local Remedy:** Use resistant maize varieties if available. Apply appropriate fungicides if the infection is severe, following label directions. To prevent future outbreaks, improve air circulation by not overcrowding plants and destroy infected crop debris after harvest.
|
| 81 |
-
## Leaf Blight
|
| 82 |
-
**Symptoms:** Large, irregular, grayish-green or tan lesions on the leaves, often appearing cigar-shaped. These lesions can grow and merge, leading to significant leaf death.
|
| 83 |
-
**Cause:** Fungal pathogens that thrive in warm, humid conditions.
|
| 84 |
-
**Local Remedy:** The primary defense is planting resistant hybrids. Fungicide applications may be necessary and should be timed based on disease scouting and weather forecasts. Crop rotation and tilling under infected residue can help reduce the pathogen for the next season.
|
| 85 |
-
## Healthy Plant
|
| 86 |
-
**Symptoms:** Vigorous growth with lush, uniformly dark green leaves. No visible spots, lesions, or discoloration.
|
| 87 |
-
**Local Remedy:** No remedy needed. Maintain good agricultural practices, including proper watering, fertilization, and pest management to keep the plant healthy.
|
| 88 |
-
"""
|
| 89 |
-
with open("knowledge.txt", "w") as f:
|
| 90 |
-
f.write(remedy_knowledge_text)
|
| 91 |
-
loader = TextLoader("knowledge.txt")
|
| 92 |
-
documents = loader.load()
|
| 93 |
-
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
|
| 94 |
-
docs = text_splitter.split_documents(documents)
|
| 95 |
-
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
|
| 96 |
-
db = FAISS.from_documents(docs, embeddings)
|
| 97 |
-
RETRIEVER = db.as_retriever(search_kwargs={"k": 1})
|
| 98 |
-
print("β
RAG knowledge base and retriever created successfully!")
|
| 99 |
-
|
| 100 |
-
except Exception as e:
|
| 101 |
-
print(f"β CRITICAL ERROR during global setup: {e}")
|
| 102 |
-
pass
|
| 103 |
-
|
| 104 |
-
# --- Step 2: Initialize ADK Tools and Agent ---
|
| 105 |
-
|
| 106 |
-
print("Initializing ADK Tools and Agent...")
|
| 107 |
-
DIAGNOSIS_TOOL = None
|
| 108 |
-
REMEDY_TOOL = None
|
| 109 |
-
ADK_AGENT = None
|
| 110 |
-
ADK_RUNNER = None
|
| 111 |
-
SESSION_SERVICE = None
|
| 112 |
-
|
| 113 |
-
try:
|
| 114 |
-
if VISION_MODEL and PROCESSOR and RETRIEVER:
|
| 115 |
-
DIAGNOSIS_TOOL = create_plant_diagnosis_tool(model=VISION_MODEL, processor=PROCESSOR)
|
| 116 |
-
REMEDY_TOOL = create_remedy_retrieval_tool(retriever=RETRIEVER)
|
| 117 |
-
|
| 118 |
-
ADK_AGENT = Agent(
|
| 119 |
-
name="AuraMindGlowAgent",
|
| 120 |
-
model="gemini-2.5-flash",
|
| 121 |
-
description="A farming assistant that can diagnose plant health and suggest remedies.",
|
| 122 |
-
instruction="You are a friendly farming assistant. Your goal is to help users identify plant health issues and find solutions. Use your tools to diagnose the plant from an image and then find a remedy.",
|
| 123 |
-
tools=[DIAGNOSIS_TOOL, REMEDY_TOOL]
|
| 124 |
-
)
|
| 125 |
-
|
| 126 |
-
SESSION_SERVICE = InMemorySessionService()
|
| 127 |
-
ADK_RUNNER = Runner(agent=ADK_AGENT, app_name="AuraMindGlow", session_service=SESSION_SERVICE)
|
| 128 |
-
print("β
ADK Agent and Runner initialized successfully!")
|
| 129 |
-
else:
|
| 130 |
-
print("β Skipping ADK setup due to errors in model or RAG loading.")
|
| 131 |
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
|
|
|
|
|
|
| 135 |
|
| 136 |
|
| 137 |
# --- Step 3: Define Gradio UIs ---
|
| 138 |
|
| 139 |
def create_field_mode_ui():
|
| 140 |
"""Creates the Gradio UI for the offline Field Mode."""
|
| 141 |
-
|
| 142 |
def get_diagnosis_and_remedy(uploaded_image: Image.Image) -> str:
|
| 143 |
if uploaded_image is None:
|
| 144 |
return "Please upload an image of a maize plant first."
|
| 145 |
if RETRIEVER is None:
|
| 146 |
raise gr.Error("Knowledge base is not loaded. Cannot find remedy. Check logs.")
|
| 147 |
-
|
| 148 |
temp_file_path = None
|
| 149 |
try:
|
| 150 |
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as temp_file:
|
|
@@ -158,7 +62,7 @@ def create_field_mode_ui():
|
|
| 158 |
return f"Sorry, I couldn't identify the condition from the image. Raw output: {diagnosis}"
|
| 159 |
|
| 160 |
remedy = REMEDY_TOOL(diagnosis)
|
| 161 |
-
|
| 162 |
final_response = f"""
|
| 163 |
## Diagnosis Report
|
| 164 |
|
|
@@ -192,18 +96,19 @@ def create_field_mode_ui():
|
|
| 192 |
outputs=gr.Markdown(label="Diagnosis and Remedy Report", value="The report will appear here..."),
|
| 193 |
title="π½ Aura Mind Glow: Field Mode (Offline)",
|
| 194 |
description="**A 100% Offline-Capable Farming Assistant.** Upload an image of a maize plant. The AI will diagnose its condition and retrieve a treatment plan from its local knowledge base.",
|
| 195 |
-
article="<p style='text-align: center;'>Built with Unsloth, LangChain, and Gradio. Version
|
| 196 |
allow_flagging="never",
|
| 197 |
theme=gr.themes.Soft(primary_hue="teal", secondary_hue="orange"),
|
| 198 |
css=css
|
| 199 |
)
|
| 200 |
|
|
|
|
| 201 |
def create_connected_mode_ui():
|
| 202 |
"""Creates the Gradio UI for the online Connected Mode."""
|
| 203 |
with gr.Blocks(theme=gr.themes.Soft(primary_hue="green", secondary_hue="lime")) as demo:
|
| 204 |
gr.Markdown("# π½ Aura Mind Glow: Connected Mode π€")
|
| 205 |
gr.Markdown("I am an AI farming assistant. Upload an image to get started.")
|
| 206 |
-
|
| 207 |
chatbot = gr.Chatbot()
|
| 208 |
msg = gr.MultimodalTextbox(file_types=["image"], label="Upload an image for diagnosis")
|
| 209 |
|
|
@@ -222,9 +127,10 @@ def create_connected_mode_ui():
|
|
| 222 |
return history, gr.MultimodalTextbox(value=None)
|
| 223 |
|
| 224 |
msg.submit(respond, [msg, chatbot], [chatbot, msg])
|
| 225 |
-
|
| 226 |
return demo
|
| 227 |
|
|
|
|
| 228 |
# --- Step 4: App Launcher ---
|
| 229 |
|
| 230 |
def check_internet_connection(host="8.8.8.8", port=53, timeout=3):
|
|
@@ -236,6 +142,7 @@ def check_internet_connection(host="8.8.8.8", port=53, timeout=3):
|
|
| 236 |
except socket.error:
|
| 237 |
return False
|
| 238 |
|
|
|
|
| 239 |
if __name__ == "__main__":
|
| 240 |
if check_internet_connection() and ADK_RUNNER:
|
| 241 |
print("β
Internet connection detected. Launching Connected Mode.")
|
|
@@ -243,5 +150,5 @@ if __name__ == "__main__":
|
|
| 243 |
else:
|
| 244 |
print("β No internet connection or ADK setup failed. Launching Field Mode (Offline).")
|
| 245 |
ui = create_field_mode_ui()
|
| 246 |
-
|
| 247 |
-
ui.launch(share=True, debug=True)
|
|
|
|
| 1 |
# ==============================================================================
|
| 2 |
+
# Aura Mind Glow - Main Application (Refactored)
|
| 3 |
# ==============================================================================
|
| 4 |
"""
|
| 5 |
This script launches the Aura Mind Glow application.
|
|
|
|
|
|
|
|
|
|
| 6 |
"""
|
| 7 |
|
| 8 |
# --- Step 0: Essential Imports ---
|
| 9 |
import gradio as gr
|
|
|
|
| 10 |
from PIL import Image
|
| 11 |
import os
|
| 12 |
import warnings
|
| 13 |
import socket
|
|
|
|
| 14 |
import tempfile
|
| 15 |
|
| 16 |
# Suppress potential warnings for a cleaner console
|
| 17 |
warnings.filterwarnings("ignore")
|
| 18 |
+
os.environ["TORCH_COMPILE_DISABLE"] = "1" # Ensure torch compile is off
|
| 19 |
|
| 20 |
+
# --- Step 1: Import Core Components from Modules ---
|
| 21 |
+
from vision_model import load_vision_model
|
| 22 |
+
from knowledge_base import get_retriever
|
| 23 |
+
from agent_setup import initialize_adk
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
print("β
All libraries imported successfully.")
|
| 26 |
|
| 27 |
+
# --- Step 2: Global Initialization ---
|
| 28 |
# This expensive setup runs only ONCE when the application starts.
|
| 29 |
|
| 30 |
+
print("Performing initial setup...")
|
| 31 |
+
VISION_MODEL, PROCESSOR = load_vision_model()
|
| 32 |
+
RETRIEVER = get_retriever()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
|
| 34 |
+
# Initialize ADK components
|
| 35 |
+
adk_components = initialize_adk(VISION_MODEL, PROCESSOR, RETRIEVER)
|
| 36 |
+
ADK_RUNNER = adk_components["runner"] if adk_components else None
|
| 37 |
+
DIAGNOSIS_TOOL = adk_components["diagnosis_tool"] if adk_components else None
|
| 38 |
+
REMEDY_TOOL = adk_components["remedy_tool"] if adk_components else None
|
| 39 |
|
| 40 |
|
| 41 |
# --- Step 3: Define Gradio UIs ---
|
| 42 |
|
| 43 |
def create_field_mode_ui():
|
| 44 |
"""Creates the Gradio UI for the offline Field Mode."""
|
| 45 |
+
|
| 46 |
def get_diagnosis_and_remedy(uploaded_image: Image.Image) -> str:
|
| 47 |
if uploaded_image is None:
|
| 48 |
return "Please upload an image of a maize plant first."
|
| 49 |
if RETRIEVER is None:
|
| 50 |
raise gr.Error("Knowledge base is not loaded. Cannot find remedy. Check logs.")
|
| 51 |
+
|
| 52 |
temp_file_path = None
|
| 53 |
try:
|
| 54 |
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as temp_file:
|
|
|
|
| 62 |
return f"Sorry, I couldn't identify the condition from the image. Raw output: {diagnosis}"
|
| 63 |
|
| 64 |
remedy = REMEDY_TOOL(diagnosis)
|
| 65 |
+
|
| 66 |
final_response = f"""
|
| 67 |
## Diagnosis Report
|
| 68 |
|
|
|
|
| 96 |
outputs=gr.Markdown(label="Diagnosis and Remedy Report", value="The report will appear here..."),
|
| 97 |
title="π½ Aura Mind Glow: Field Mode (Offline)",
|
| 98 |
description="**A 100% Offline-Capable Farming Assistant.** Upload an image of a maize plant. The AI will diagnose its condition and retrieve a treatment plan from its local knowledge base.",
|
| 99 |
+
article="<p style='text-align: center;'>Built with Unsloth, LangChain, and Gradio. Version 2.0</p>",
|
| 100 |
allow_flagging="never",
|
| 101 |
theme=gr.themes.Soft(primary_hue="teal", secondary_hue="orange"),
|
| 102 |
css=css
|
| 103 |
)
|
| 104 |
|
| 105 |
+
|
| 106 |
def create_connected_mode_ui():
|
| 107 |
"""Creates the Gradio UI for the online Connected Mode."""
|
| 108 |
with gr.Blocks(theme=gr.themes.Soft(primary_hue="green", secondary_hue="lime")) as demo:
|
| 109 |
gr.Markdown("# π½ Aura Mind Glow: Connected Mode π€")
|
| 110 |
gr.Markdown("I am an AI farming assistant. Upload an image to get started.")
|
| 111 |
+
|
| 112 |
chatbot = gr.Chatbot()
|
| 113 |
msg = gr.MultimodalTextbox(file_types=["image"], label="Upload an image for diagnosis")
|
| 114 |
|
|
|
|
| 127 |
return history, gr.MultimodalTextbox(value=None)
|
| 128 |
|
| 129 |
msg.submit(respond, [msg, chatbot], [chatbot, msg])
|
| 130 |
+
|
| 131 |
return demo
|
| 132 |
|
| 133 |
+
|
| 134 |
# --- Step 4: App Launcher ---
|
| 135 |
|
| 136 |
def check_internet_connection(host="8.8.8.8", port=53, timeout=3):
|
|
|
|
| 142 |
except socket.error:
|
| 143 |
return False
|
| 144 |
|
| 145 |
+
|
| 146 |
if __name__ == "__main__":
|
| 147 |
if check_internet_connection() and ADK_RUNNER:
|
| 148 |
print("β
Internet connection detected. Launching Connected Mode.")
|
|
|
|
| 150 |
else:
|
| 151 |
print("β No internet connection or ADK setup failed. Launching Field Mode (Offline).")
|
| 152 |
ui = create_field_mode_ui()
|
| 153 |
+
|
| 154 |
+
ui.launch(share=True, debug=True)
|
app2.py
DELETED
|
@@ -1,247 +0,0 @@
|
|
| 1 |
-
# ==============================================================================
|
| 2 |
-
# Aura Mind Glow - Main Application
|
| 3 |
-
# ==============================================================================
|
| 4 |
-
"""
|
| 5 |
-
This script launches the Aura Mind Glow application.
|
| 6 |
-
It features two modes:
|
| 7 |
-
1. Field Mode (100% Offline): For quick diagnosis and remedy retrieval.
|
| 8 |
-
2. Connected Mode (Online): A conversational agent powered by the Google ADK.
|
| 9 |
-
"""
|
| 10 |
-
|
| 11 |
-
# --- Step 0: Essential Imports ---
|
| 12 |
-
import gradio as gr
|
| 13 |
-
import torch
|
| 14 |
-
from PIL import Image
|
| 15 |
-
import os
|
| 16 |
-
import warnings
|
| 17 |
-
import socket
|
| 18 |
-
import asyncio
|
| 19 |
-
import tempfile
|
| 20 |
-
|
| 21 |
-
# Suppress potential warnings for a cleaner console
|
| 22 |
-
warnings.filterwarnings("ignore")
|
| 23 |
-
os.environ["TORCH_COMPILE_DISABLE"] = "1" # Ensure torch compile is off
|
| 24 |
-
|
| 25 |
-
# Unsloth and Transformers
|
| 26 |
-
from unsloth import FastVisionModel
|
| 27 |
-
from transformers import AutoProcessor
|
| 28 |
-
|
| 29 |
-
# LangChain and RAG components
|
| 30 |
-
from langchain_community.vectorstores import FAISS
|
| 31 |
-
from langchain_community.document_loaders import TextLoader
|
| 32 |
-
from langchain_huggingface import HuggingFaceEmbeddings
|
| 33 |
-
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
| 34 |
-
|
| 35 |
-
# Google ADK
|
| 36 |
-
from google.adk import Agent, Runner
|
| 37 |
-
from google.adk.sessions import InMemorySessionService
|
| 38 |
-
from google.genai import types
|
| 39 |
-
|
| 40 |
-
# Custom Tools
|
| 41 |
-
from tools import create_plant_diagnosis_tool, create_remedy_retrieval_tool
|
| 42 |
-
|
| 43 |
-
print("β
All libraries imported successfully.")
|
| 44 |
-
|
| 45 |
-
# --- Step 1: Global Setup - Vision Model and RAG ---
|
| 46 |
-
# This expensive setup runs only ONCE when the application starts.
|
| 47 |
-
|
| 48 |
-
print("Performing initial setup for Vision Model and RAG...")
|
| 49 |
-
VISION_MODEL = None
|
| 50 |
-
PROCESSOR = None
|
| 51 |
-
RETRIEVER = None
|
| 52 |
-
ADAPTER_PATH = "surfiniaburger/maize-health-diagnosis-adapter"
|
| 53 |
-
|
| 54 |
-
try:
|
| 55 |
-
# Load Vision Model
|
| 56 |
-
VISION_MODEL, PROCESSOR = FastVisionModel.from_pretrained(
|
| 57 |
-
model_name="unsloth/gemma-3n-E2B-it-unsloth-bnb-4bit",
|
| 58 |
-
max_seq_length=2048,
|
| 59 |
-
load_in_4bit=True,
|
| 60 |
-
dtype=None,
|
| 61 |
-
)
|
| 62 |
-
FastVisionModel.for_inference(VISION_MODEL)
|
| 63 |
-
VISION_MODEL.load_adapter(ADAPTER_PATH)
|
| 64 |
-
print(f"β
Vision model and adapter '{ADAPTER_PATH}' loaded successfully!")
|
| 65 |
-
|
| 66 |
-
# Build RAG Knowledge Base
|
| 67 |
-
remedy_knowledge_text = """
|
| 68 |
-
# Maize Health Guide
|
| 69 |
-
## Phosphorus Deficiency
|
| 70 |
-
**Symptoms:** Plants are often stunted, dark green or purplish. This condition is sometimes called Purple leaf disease. The purplish discoloration is most evident on the tips of leaves of young plants.
|
| 71 |
-
**Cause:** Lack of available phosphorus in the soil, often due to incorrect pH or cold soil temperatures.
|
| 72 |
-
**Local Remedy:** Apply a high-phosphorus starter fertilizer at planting time. In organic systems, bone meal or rock phosphate are excellent sources. A foliar spray of a water-soluable phosphate fertilizer can be applied directly to the leaves for a quick, short-term fix. Ensure soil pH is between 6.0 and 7.0 for optimal phosphorus uptake.
|
| 73 |
-
## Nitrogen Deficiency
|
| 74 |
-
**Symptoms:** General yellowing (chlorosis) of the plant, starting with the lower, older leaves in a distinct "V" shape that progresses up the midrib.
|
| 75 |
-
**Cause:** Insufficient nitrogen in the soil, which is a mobile nutrient.
|
| 76 |
-
**Local Remedy:** Side-dress with a nitrogen-rich fertilizer like urea, ammonium nitrate, or composted manure whenplants are about knee-high. For organic farming, blood meal or feather meal are effective sources.
|
| 77 |
-
## Leaf Spot
|
| 78 |
-
**Symptoms:** Small, circular to oval spots with tan centers and dark borders on the leaves. This is a common fungal disease.
|
| 79 |
-
**Cause:** Fungal pathogens that spread via water splash and wind.
|
| 80 |
-
**Local Remedy:** Use resistant maize varieties if available. Apply appropriate fungicides if the infection is severe, following label directions. To prevent future outbreaks, improve air circulation by not overcrowding plants and destroy infected crop debris after harvest.
|
| 81 |
-
## Leaf Blight
|
| 82 |
-
**Symptoms:** Large, irregular, grayish-green or tan lesions on the leaves, often appearing cigar-shaped. These lesions can grow and merge, leading to significant leaf death.
|
| 83 |
-
**Cause:** Fungal pathogens that thrive in warm, humid conditions.
|
| 84 |
-
**Local Remedy:** The primary defense is planting resistant hybrids. Fungicide applications may be necessary and should be timed based on disease scouting and weather forecasts. Crop rotation and tilling under infected residue can help reduce the pathogen for the next season.
|
| 85 |
-
## Healthy Plant
|
| 86 |
-
**Symptoms:** Vigorous growth with lush, uniformly dark green leaves. No visible spots, lesions, or discoloration.
|
| 87 |
-
**Local Remedy:** No remedy needed. Maintain good agricultural practices, including proper watering, fertilization, and pest management to keep the plant healthy.
|
| 88 |
-
"""
|
| 89 |
-
with open("knowledge.txt", "w") as f:
|
| 90 |
-
f.write(remedy_knowledge_text)
|
| 91 |
-
loader = TextLoader("knowledge.txt")
|
| 92 |
-
documents = loader.load()
|
| 93 |
-
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
|
| 94 |
-
docs = text_splitter.split_documents(documents)
|
| 95 |
-
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
|
| 96 |
-
db = FAISS.from_documents(docs, embeddings)
|
| 97 |
-
RETRIEVER = db.as_retriever(search_kwargs={"k": 1})
|
| 98 |
-
print("β
RAG knowledge base and retriever created successfully!")
|
| 99 |
-
|
| 100 |
-
except Exception as e:
|
| 101 |
-
print(f"β CRITICAL ERROR during global setup: {e}")
|
| 102 |
-
pass
|
| 103 |
-
|
| 104 |
-
# --- Step 2: Initialize ADK Tools and Agent ---
|
| 105 |
-
|
| 106 |
-
print("Initializing ADK Tools and Agent...")
|
| 107 |
-
DIAGNOSIS_TOOL = None
|
| 108 |
-
REMEDY_TOOL = None
|
| 109 |
-
ADK_AGENT = None
|
| 110 |
-
ADK_RUNNER = None
|
| 111 |
-
SESSION_SERVICE = None
|
| 112 |
-
|
| 113 |
-
try:
|
| 114 |
-
if VISION_MODEL and PROCESSOR and RETRIEVER:
|
| 115 |
-
DIAGNOSIS_TOOL = create_plant_diagnosis_tool(model=VISION_MODEL, processor=PROCESSOR)
|
| 116 |
-
REMEDY_TOOL = create_remedy_retrieval_tool(retriever=RETRIEVER)
|
| 117 |
-
|
| 118 |
-
ADK_AGENT = Agent(
|
| 119 |
-
name="AuraMindGlowAgent",
|
| 120 |
-
model="gemini-2.5-flash",
|
| 121 |
-
description="A farming assistant that can diagnose plant health and suggest remedies.",
|
| 122 |
-
instruction="You are a friendly farming assistant. Your goal is to help users identify plant health issues and find solutions. Use your tools to diagnose the plant from an image and then find a remedy.",
|
| 123 |
-
tools=[DIAGNOSIS_TOOL, REMEDY_TOOL]
|
| 124 |
-
)
|
| 125 |
-
|
| 126 |
-
SESSION_SERVICE = InMemorySessionService()
|
| 127 |
-
ADK_RUNNER = Runner(agent=ADK_AGENT, app_name="AuraMindGlow", session_service=SESSION_SERVICE)
|
| 128 |
-
print("β
ADK Agent and Runner initialized successfully!")
|
| 129 |
-
else:
|
| 130 |
-
print("β Skipping ADK setup due to errors in model or RAG loading.")
|
| 131 |
-
|
| 132 |
-
except Exception as e:
|
| 133 |
-
print(f"β CRITICAL ERROR during ADK setup: {e}")
|
| 134 |
-
pass
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
# --- Step 3: Define Gradio UIs ---
|
| 138 |
-
|
| 139 |
-
def create_field_mode_ui():
|
| 140 |
-
"""Creates the Gradio UI for the offline Field Mode."""
|
| 141 |
-
|
| 142 |
-
def get_diagnosis_and_remedy(uploaded_image: Image.Image) -> str:
|
| 143 |
-
if uploaded_image is None:
|
| 144 |
-
return "Please upload an image of a maize plant first."
|
| 145 |
-
if RETRIEVER is None:
|
| 146 |
-
raise gr.Error("Knowledge base is not loaded. Cannot find remedy. Check logs.")
|
| 147 |
-
|
| 148 |
-
temp_file_path = None
|
| 149 |
-
try:
|
| 150 |
-
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as temp_file:
|
| 151 |
-
uploaded_image.save(temp_file.name)
|
| 152 |
-
temp_file_path = temp_file.name
|
| 153 |
-
|
| 154 |
-
diagnosis = DIAGNOSIS_TOOL(temp_file_path)
|
| 155 |
-
print(f"Diagnosis received: {diagnosis}")
|
| 156 |
-
|
| 157 |
-
if "Could not parse" in diagnosis:
|
| 158 |
-
return f"Sorry, I couldn't identify the condition from the image. Raw output: {diagnosis}"
|
| 159 |
-
|
| 160 |
-
remedy = REMEDY_TOOL(diagnosis)
|
| 161 |
-
|
| 162 |
-
final_response = f"""
|
| 163 |
-
## Diagnosis Report
|
| 164 |
-
|
| 165 |
-
**Condition Identified:**
|
| 166 |
-
### {diagnosis}
|
| 167 |
-
|
| 168 |
-
---
|
| 169 |
-
|
| 170 |
-
## Suggested Remedy
|
| 171 |
-
|
| 172 |
-
{remedy}
|
| 173 |
-
"""
|
| 174 |
-
print("Workflow complete. Returning response.")
|
| 175 |
-
return final_response
|
| 176 |
-
|
| 177 |
-
except Exception as e:
|
| 178 |
-
print(f"An error occurred during the analysis workflow: {e}")
|
| 179 |
-
raise gr.Error(f"An unexpected error occurred: {e}")
|
| 180 |
-
finally:
|
| 181 |
-
if temp_file_path and os.path.exists(temp_file_path):
|
| 182 |
-
os.remove(temp_file_path)
|
| 183 |
-
|
| 184 |
-
css = """
|
| 185 |
-
footer {visibility: hidden !important;}
|
| 186 |
-
.gradio-container {font-family: 'IBM Plex Sans', sans-serif;}
|
| 187 |
-
"""
|
| 188 |
-
|
| 189 |
-
return gr.Interface(
|
| 190 |
-
fn=get_diagnosis_and_remedy,
|
| 191 |
-
inputs=gr.Image(type="pil", label="Upload Maize Plant Image", sources=["upload", "webcam"]),
|
| 192 |
-
outputs=gr.Markdown(label="Diagnosis and Remedy Report", value="The report will appear here..."),
|
| 193 |
-
title="π½ Aura Mind Glow: Field Mode (Offline)",
|
| 194 |
-
description="**A 100% Offline-Capable Farming Assistant.** Upload an image of a maize plant. The AI will diagnose its condition and retrieve a treatment plan from its local knowledge base.",
|
| 195 |
-
article="<p style='text-align: center;'>Built with Unsloth, LangChain, and Gradio. Version 1.3</p>",
|
| 196 |
-
allow_flagging="never",
|
| 197 |
-
theme=gr.themes.Soft(primary_hue="teal", secondary_hue="orange"),
|
| 198 |
-
css=css
|
| 199 |
-
)
|
| 200 |
-
|
| 201 |
-
def create_connected_mode_ui():
|
| 202 |
-
"""Creates the Gradio UI for the online Connected Mode."""
|
| 203 |
-
with gr.Blocks(theme=gr.themes.Soft(primary_hue="green", secondary_hue="lime")) as demo:
|
| 204 |
-
gr.Markdown("# π½ Aura Mind Glow: Connected Mode π€")
|
| 205 |
-
gr.Markdown("I am an AI farming assistant. Upload an image to get started.")
|
| 206 |
-
|
| 207 |
-
chatbot = gr.Chatbot()
|
| 208 |
-
msg = gr.MultimodalTextbox(file_types=["image"], label="Upload an image for diagnosis")
|
| 209 |
-
|
| 210 |
-
async def respond(chat_input, history):
|
| 211 |
-
files = chat_input["files"]
|
| 212 |
-
if files:
|
| 213 |
-
file_path = files[0]
|
| 214 |
-
# Directly call the diagnosis tool for testing
|
| 215 |
-
diagnosis = DIAGNOSIS_TOOL(file_path)
|
| 216 |
-
bot_message = f"**Diagnosis:** {diagnosis}"
|
| 217 |
-
history.append([(file_path,), bot_message])
|
| 218 |
-
else:
|
| 219 |
-
bot_message = "Please upload an image for diagnosis."
|
| 220 |
-
history.append([chat_input["text"], bot_message])
|
| 221 |
-
|
| 222 |
-
return history, gr.MultimodalTextbox(value=None)
|
| 223 |
-
|
| 224 |
-
msg.submit(respond, [msg, chatbot], [chatbot, msg])
|
| 225 |
-
|
| 226 |
-
return demo
|
| 227 |
-
|
| 228 |
-
# --- Step 4: App Launcher ---
|
| 229 |
-
|
| 230 |
-
def check_internet_connection(host="8.8.8.8", port=53, timeout=3):
|
| 231 |
-
"""Check for internet connectivity."""
|
| 232 |
-
try:
|
| 233 |
-
socket.setdefaulttimeout(timeout)
|
| 234 |
-
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))
|
| 235 |
-
return True
|
| 236 |
-
except socket.error:
|
| 237 |
-
return False
|
| 238 |
-
|
| 239 |
-
if __name__ == "__main__":
|
| 240 |
-
if check_internet_connection() and ADK_RUNNER:
|
| 241 |
-
print("β
Internet connection detected. Launching Connected Mode.")
|
| 242 |
-
ui = create_connected_mode_ui()
|
| 243 |
-
else:
|
| 244 |
-
print("β No internet connection or ADK setup failed. Launching Field Mode (Offline).")
|
| 245 |
-
ui = create_field_mode_ui()
|
| 246 |
-
|
| 247 |
-
ui.launch(share=True, debug=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
config.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Configuration for the Aura Mind Glow application
|
| 2 |
+
|
| 3 |
+
# Model and Adapter Paths
|
| 4 |
+
VISION_MODEL_NAME = "unsloth/gemma-3n-E2B-it-unsloth-bnb-4bit"
|
| 5 |
+
ADAPTER_PATH = "surfiniaburger/maize-health-diagnosis-adapter"
|
| 6 |
+
EMBEDDING_MODEL_NAME = "sentence-transformers/all-MiniLM-L6-v2"
|
| 7 |
+
|
| 8 |
+
# RAG and Knowledge Base
|
| 9 |
+
KNOWLEDGE_BASE_PATH = "knowledge_base.md"
|
| 10 |
+
FAISS_INDEX_PATH = "faiss_index"
|
| 11 |
+
|
| 12 |
+
# Model Parameters
|
| 13 |
+
MAX_SEQ_LENGTH = 2048
|
knowledge_base.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Maize Health Guide
|
| 2 |
+
## Phosphorus Deficiency
|
| 3 |
+
**Symptoms:** Plants are often stunted, dark green or purplish. This condition is sometimes called Purple leaf disease. The purplish discoloration is most evident on the tips of leaves of young plants.
|
| 4 |
+
**Cause:** Lack of available phosphorus in the soil, often due to incorrect pH or cold soil temperatures.
|
| 5 |
+
**Local Remedy:** Apply a high-phosphorus starter fertilizer at planting time. In organic systems, bone meal or rock phosphate are excellent sources. A foliar spray of a water-soluable phosphate fertilizer can be applied directly to the leaves for a quick, short-term fix. Ensure soil pH is between 6.0 and 7.0 for optimal phosphorus uptake.
|
| 6 |
+
## Nitrogen Deficiency
|
| 7 |
+
**Symptoms:** General yellowing (chlorosis) of the plant, starting with the lower, older leaves in a distinct "V" shape that progresses up the midrib.
|
| 8 |
+
**Cause:** Insufficient nitrogen in the soil, which is a mobile nutrient.
|
| 9 |
+
**Local Remedy:** Side-dress with a nitrogen-rich fertilizer like urea, ammonium nitrate, or composted manure whenplants are about knee-high. For organic farming, blood meal or feather meal are effective sources.
|
| 10 |
+
## Leaf Spot
|
| 11 |
+
**Symptoms:** Small, circular to oval spots with tan centers and dark borders on the leaves. This is a common fungal disease.
|
| 12 |
+
**Cause:** Fungal pathogens that spread via water splash and wind.
|
| 13 |
+
**Local Remedy:** Use resistant maize varieties if available. Apply appropriate fungicides if the infection is severe, following label directions. To prevent future outbreaks, improve air circulation by not overcrowding plants and destroy infected crop debris after harvest.
|
| 14 |
+
## Leaf Blight
|
| 15 |
+
**Symptoms:** Large, irregular, grayish-green or tan lesions on the leaves, often appearing cigar-shaped. These lesions can grow and merge, leading to significant leaf death.
|
| 16 |
+
**Cause:** Fungal pathogens that thrive in warm, humid conditions.
|
| 17 |
+
**Local Remedy:** The primary defense is planting resistant hybrids. Fungicide applications may be necessary and should be timed based on disease scouting and weather forecasts. Crop rotation and tilling under infected residue can help reduce the pathogen for the next season.
|
| 18 |
+
## Healthy Plant
|
| 19 |
+
**Symptoms:** Vigorous growth with lush, uniformly dark green leaves. No visible spots, lesions, or discoloration.
|
| 20 |
+
**Local Remedy:** No remedy needed. Maintain good agricultural practices, including proper watering, fertilization, and pest management to keep the plant healthy.
|
knowledge_base.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from langchain_community.vectorstores import FAISS
|
| 3 |
+
from langchain_community.document_loaders import TextLoader
|
| 4 |
+
from langchain_huggingface import HuggingFaceEmbeddings
|
| 5 |
+
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
| 6 |
+
import config
|
| 7 |
+
|
| 8 |
+
def get_retriever():
|
| 9 |
+
"""
|
| 10 |
+
Creates or loads a FAISS vector store and returns a retriever.
|
| 11 |
+
|
| 12 |
+
Returns:
|
| 13 |
+
A FAISS retriever object, or None on error.
|
| 14 |
+
"""
|
| 15 |
+
try:
|
| 16 |
+
embeddings = HuggingFaceEmbeddings(model_name=config.EMBEDDING_MODEL_NAME)
|
| 17 |
+
|
| 18 |
+
if os.path.exists(config.FAISS_INDEX_PATH):
|
| 19 |
+
print(f"β
Loading existing FAISS index from {config.FAISS_INDEX_PATH}...")
|
| 20 |
+
db = FAISS.load_local(config.FAISS_INDEX_PATH, embeddings, allow_dangerous_deserialization=True)
|
| 21 |
+
else:
|
| 22 |
+
print(f"β οΈ FAISS index not found. Building a new one from {config.KNOWLEDGE_BASE_PATH}...")
|
| 23 |
+
loader = TextLoader(config.KNOWLEDGE_BASE_PATH)
|
| 24 |
+
documents = loader.load()
|
| 25 |
+
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
|
| 26 |
+
docs = text_splitter.split_documents(documents)
|
| 27 |
+
db = FAISS.from_documents(docs, embeddings)
|
| 28 |
+
db.save_local(config.FAISS_INDEX_PATH)
|
| 29 |
+
print(f"β
New FAISS index built and saved to {config.FAISS_INDEX_PATH}.")
|
| 30 |
+
|
| 31 |
+
retriever = db.as_retriever(search_kwargs={"k": 1})
|
| 32 |
+
print("β
RAG knowledge base and retriever created successfully!")
|
| 33 |
+
return retriever
|
| 34 |
+
except Exception as e:
|
| 35 |
+
print(f"β CRITICAL ERROR during RAG setup: {e}")
|
| 36 |
+
return None
|
vision_model.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
from unsloth import FastVisionModel
|
| 3 |
+
from transformers import AutoProcessor
|
| 4 |
+
import config
|
| 5 |
+
|
| 6 |
+
def load_vision_model():
|
| 7 |
+
"""
|
| 8 |
+
Loads the FastVisionModel and its adapter for inference.
|
| 9 |
+
|
| 10 |
+
Returns:
|
| 11 |
+
A tuple containing the loaded model and processor, or (None, None) on error.
|
| 12 |
+
"""
|
| 13 |
+
try:
|
| 14 |
+
model, processor = FastVisionModel.from_pretrained(
|
| 15 |
+
model_name=config.VISION_MODEL_NAME,
|
| 16 |
+
max_seq_length=config.MAX_SEQ_LENGTH,
|
| 17 |
+
load_in_4bit=True,
|
| 18 |
+
dtype=None,
|
| 19 |
+
)
|
| 20 |
+
FastVisionModel.for_inference(model)
|
| 21 |
+
model.load_adapter(config.ADAPTER_PATH)
|
| 22 |
+
print(f"β
Vision model and adapter '{config.ADAPTER_PATH}' loaded successfully!")
|
| 23 |
+
return model, processor
|
| 24 |
+
except Exception as e:
|
| 25 |
+
print(f"β CRITICAL ERROR during vision model loading: {e}")
|
| 26 |
+
return None, None
|