hari7261 commited on
Commit
b1883a0
Β·
verified Β·
1 Parent(s): 2aacfcc

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +1172 -0
app.py ADDED
@@ -0,0 +1,1172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ import random
3
+ import gradio as gr
4
+ import json
5
+ import os
6
+ from typing import Dict, List, Any
7
+
8
+ # Try to import AI libraries
9
+ try:
10
+ import openai
11
+ OPENAI_AVAILABLE = True
12
+ except ImportError:
13
+ OPENAI_AVAILABLE = False
14
+
15
+ try:
16
+ from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
17
+ import torch
18
+ TRANSFORMERS_AVAILABLE = True
19
+ except ImportError:
20
+ TRANSFORMERS_AVAILABLE = False
21
+
22
+ # Try to import sentence transformers for semantic search
23
+ try:
24
+ from sentence_transformers import SentenceTransformer
25
+ import numpy as np
26
+ SENTENCE_TRANSFORMERS_AVAILABLE = True
27
+ except ImportError:
28
+ SENTENCE_TRANSFORMERS_AVAILABLE = False
29
+
30
+ class AgriBot:
31
+ def __init__(self):
32
+ self.name = "AgriBot"
33
+ self.user_name = ""
34
+ self.conversation_history = []
35
+ self.model_loaded = False
36
+ self.generator = None
37
+ self.tokenizer = None
38
+ self.model = None
39
+ self.embedding_model = None
40
+
41
+ # Load agricultural data from JSON
42
+ self.agricultural_data = self.load_agricultural_data()
43
+ self.knowledge_base = self.prepare_knowledge_base()
44
+
45
+ # Initialize embedding model for semantic search
46
+ self.init_embedding_model()
47
+
48
+ def load_agricultural_data(self) -> Dict:
49
+ """Load agricultural data from JSON file"""
50
+ try:
51
+ json_path = os.path.join(os.path.dirname(__file__), 'agricultural_data.json')
52
+ with open(json_path, 'r', encoding='utf-8') as file:
53
+ return json.load(file)
54
+ except FileNotFoundError:
55
+ print("Agricultural data file not found. Using basic data.")
56
+ return self.get_fallback_data()
57
+ except json.JSONDecodeError:
58
+ print("Error reading agricultural data. Using basic data.")
59
+ return self.get_fallback_data()
60
+
61
+ def get_fallback_data(self) -> Dict:
62
+ """Fallback data if JSON file is not available"""
63
+ return {
64
+ "crops": {
65
+ "rice": {
66
+ "season": "Kharif (June-November)",
67
+ "water_requirement": "High water requirement, flooded fields",
68
+ "soil": {"type": "Clay or loamy soil with good water retention"},
69
+ "fertilizer": {"npk": "120:60:40 kg/ha"},
70
+ "diseases": [{"name": "Blast"}, {"name": "Brown spot"}],
71
+ "pests": [{"name": "Stem borer"}, {"name": "Brown planthopper"}],
72
+ "market_uses": ["Staple food", "Rice flour"]
73
+ }
74
+ }
75
+ }
76
+
77
+ def prepare_knowledge_base(self) -> List[Dict]:
78
+ """Prepare searchable knowledge base from agricultural data"""
79
+ knowledge_items = []
80
+
81
+ # Process crops data
82
+ for crop_name, crop_data in self.agricultural_data.get('crops', {}).items():
83
+ # Basic crop info
84
+ knowledge_items.append({
85
+ 'type': 'crop_info',
86
+ 'crop': crop_name,
87
+ 'content': f"{crop_name} cultivation information: Season - {crop_data.get('season', 'N/A')}, "
88
+ f"Climate - {crop_data.get('climate', 'N/A')}, "
89
+ f"Soil - {crop_data.get('soil', {}).get('type', 'N/A')}, "
90
+ f"Water requirement - {crop_data.get('water_requirement', 'N/A')}",
91
+ 'data': crop_data
92
+ })
93
+
94
+ # Diseases
95
+ for disease in crop_data.get('diseases', []):
96
+ knowledge_items.append({
97
+ 'type': 'disease',
98
+ 'crop': crop_name,
99
+ 'content': f"{disease.get('name', 'Unknown')} disease in {crop_name}: "
100
+ f"Cause - {disease.get('cause', 'N/A')}, "
101
+ f"Symptoms - {disease.get('symptoms', 'N/A')}, "
102
+ f"Control - {disease.get('control', 'N/A')}",
103
+ 'data': disease
104
+ })
105
+
106
+ # Pests
107
+ for pest in crop_data.get('pests', []):
108
+ knowledge_items.append({
109
+ 'type': 'pest',
110
+ 'crop': crop_name,
111
+ 'content': f"{pest.get('name', 'Unknown')} pest in {crop_name}: "
112
+ f"Damage - {pest.get('damage', 'N/A')}, "
113
+ f"Control - {pest.get('control', 'N/A')}",
114
+ 'data': pest
115
+ })
116
+
117
+ # Process farming techniques
118
+ for technique_name, technique_data in self.agricultural_data.get('farming_techniques', {}).items():
119
+ knowledge_items.append({
120
+ 'type': 'technique',
121
+ 'content': f"{technique_name}: {technique_data.get('definition', 'N/A')}. "
122
+ f"Benefits: {', '.join(technique_data.get('benefits', []))}",
123
+ 'data': technique_data
124
+ })
125
+
126
+ return knowledge_items
127
+
128
+ def init_embedding_model(self):
129
+ """Initialize embedding model for semantic search"""
130
+ if SENTENCE_TRANSFORMERS_AVAILABLE:
131
+ try:
132
+ self.embedding_model = SentenceTransformer('all-MiniLM-L6-v2')
133
+ # Pre-compute embeddings for knowledge base
134
+ self.knowledge_embeddings = self.embedding_model.encode([item['content'] for item in self.knowledge_base])
135
+ except Exception as e:
136
+ print(f"Failed to load embedding model: {e}")
137
+ self.embedding_model = None
138
+ else:
139
+ self.embedding_model = None
140
+
141
+ def semantic_search(self, query: str, top_k: int = 3) -> List[Dict]:
142
+ """Perform semantic search on knowledge base"""
143
+ if self.embedding_model is None:
144
+ return self.fallback_search(query, top_k)
145
+
146
+ try:
147
+ query_embedding = self.embedding_model.encode([query])
148
+ similarities = np.dot(query_embedding, self.knowledge_embeddings.T)[0]
149
+ top_indices = np.argsort(similarities)[-top_k:][::-1]
150
+
151
+ results = []
152
+ for idx in top_indices:
153
+ if similarities[idx] > 0.3: # Threshold for relevance
154
+ results.append({
155
+ 'item': self.knowledge_base[idx],
156
+ 'score': float(similarities[idx])
157
+ })
158
+
159
+ return results
160
+ except Exception as e:
161
+ print(f"Semantic search error: {e}")
162
+ return self.fallback_search(query, top_k)
163
+
164
+ def fallback_search(self, query: str, top_k: int = 3) -> List[Dict]:
165
+ """Fallback search using keyword matching"""
166
+ query_words = set(query.lower().split())
167
+ results = []
168
+
169
+ for item in self.knowledge_base:
170
+ content_words = set(item['content'].lower().split())
171
+ overlap = len(query_words.intersection(content_words))
172
+ if overlap > 0:
173
+ results.append({
174
+ 'item': item,
175
+ 'score': overlap / len(query_words)
176
+ })
177
+
178
+ results.sort(key=lambda x: x['score'], reverse=True)
179
+ return results[:top_k]
180
+
181
+ def load_model(self):
182
+ """Load AI model for advanced queries"""
183
+ if self.model_loaded:
184
+ return True
185
+
186
+ if TRANSFORMERS_AVAILABLE:
187
+ try:
188
+ # Use a smaller, more reliable model
189
+ model_name = "microsoft/DialoGPT-medium"
190
+
191
+ self.tokenizer = AutoTokenizer.from_pretrained(model_name)
192
+ self.model = AutoModelForCausalLM.from_pretrained(
193
+ model_name,
194
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
195
+ device_map="auto" if torch.cuda.is_available() else None,
196
+ low_cpu_mem_usage=True
197
+ )
198
+
199
+ # Add pad token if not present
200
+ if self.tokenizer.pad_token is None:
201
+ self.tokenizer.pad_token = self.tokenizer.eos_token
202
+
203
+ self.generator = pipeline(
204
+ "text-generation",
205
+ model=self.model,
206
+ tokenizer=self.tokenizer,
207
+ device=0 if torch.cuda.is_available() else -1,
208
+ return_full_text=False
209
+ )
210
+
211
+ self.model_loaded = True
212
+ print("βœ… AI model loaded successfully!")
213
+ return True
214
+
215
+ except Exception as e:
216
+ print(f"⚠️ Could not load AI model: {str(e)}")
217
+ return False
218
+ else:
219
+ print("πŸ”§ Install transformers and torch for AI features")
220
+ return False
221
+
222
+ def generate_ai_response(self, query: str, context: str = "") -> str:
223
+ """Generate conversational AI response using agricultural data as knowledge"""
224
+ if not self.model_loaded:
225
+ if not self.load_model():
226
+ return self.generate_openai_style_response(query, context)
227
+
228
+ try:
229
+ # Create a conversational prompt that makes AI process the data
230
+ system_prompt = """You are an expert agricultural consultant with years of experience helping farmers.
231
+ Your job is to provide helpful, conversational advice based on agricultural knowledge.
232
+ Don't just list data - explain it naturally as if you're talking to a farmer.
233
+ Give practical recommendations and explain the reasoning behind them."""
234
+
235
+ user_prompt = f"""Based on this agricultural information: {context}
236
+
237
+ Please answer this farmer's question in a helpful, conversational way: {query}
238
+
239
+ Provide practical advice and explain why these recommendations work."""
240
+
241
+ # Generate response
242
+ full_prompt = f"{system_prompt}\n\nUser: {user_prompt}\nAssistant:"
243
+
244
+ response = self.generator(
245
+ full_prompt,
246
+ max_new_tokens=200,
247
+ do_sample=True,
248
+ temperature=0.8,
249
+ top_p=0.9,
250
+ pad_token_id=self.tokenizer.eos_token_id,
251
+ repetition_penalty=1.2,
252
+ no_repeat_ngram_size=3
253
+ )
254
+
255
+ if response and len(response) > 0:
256
+ generated_text = response[0]["generated_text"]
257
+ # Extract only the assistant's response
258
+ if "Assistant:" in generated_text:
259
+ ai_response = generated_text.split("Assistant:")[-1].strip()
260
+ if len(ai_response) > 20:
261
+ return ai_response
262
+
263
+ except Exception as e:
264
+ print(f"AI generation error: {e}")
265
+
266
+ # Fallback to OpenAI-style response
267
+ return self.generate_openai_style_response(query, context)
268
+
269
+ def generate_openai_style_response(self, query: str, context: str) -> str:
270
+ """Generate OpenAI-style conversational response using template"""
271
+ query_lower = query.lower()
272
+
273
+ # Extract key information from context
274
+ crop_mentioned = None
275
+ for crop in ['wheat', 'rice', 'corn', 'tomato', 'potato']:
276
+ if crop in query_lower or crop in context.lower():
277
+ crop_mentioned = crop
278
+ break
279
+
280
+ if crop_mentioned:
281
+ crop_data = self.agricultural_data.get('crops', {}).get(crop_mentioned, {})
282
+
283
+ if 'how to' in query_lower or 'grow' in query_lower or 'cultivate' in query_lower:
284
+ return self.generate_cultivation_response(crop_mentioned, crop_data, query)
285
+ elif 'fertilizer' in query_lower or 'nutrient' in query_lower:
286
+ return self.generate_fertilizer_response(crop_mentioned, crop_data)
287
+ elif 'disease' in query_lower or 'pest' in query_lower:
288
+ return self.generate_pest_disease_response(crop_mentioned, crop_data, query)
289
+ elif 'harvest' in query_lower:
290
+ return self.generate_harvest_response(crop_mentioned, crop_data)
291
+ else:
292
+ return self.generate_general_crop_response(crop_mentioned, crop_data, query)
293
+
294
+ return self.generate_general_farming_response(query, context)
295
+
296
+ def generate_cultivation_response(self, crop: str, crop_data: dict, query: str) -> str:
297
+ """Generate detailed cultivation guide response"""
298
+ season = crop_data.get('season', 'appropriate season')
299
+ climate = crop_data.get('climate', 'suitable climate conditions')
300
+ soil_info = crop_data.get('soil', {})
301
+ soil_type = soil_info.get('type', 'well-prepared soil')
302
+ water_req = crop_data.get('water_requirement', 'adequate water')
303
+
304
+ planting_info = crop_data.get('planting', {})
305
+ spacing = planting_info.get('spacing', 'proper spacing')
306
+ depth = planting_info.get('depth', 'appropriate depth')
307
+
308
+ response = f"""Great question about growing {crop}! Let me walk you through the complete cultivation process:
309
+
310
+ 🌱 **Getting Started:**
311
+ {crop.capitalize()} grows best during {season}. You'll want {climate} for optimal growth. The key is starting with {soil_type} - this gives your crop the foundation it needs.
312
+
313
+ 🌾 **Planting Process:**
314
+ When planting, maintain {spacing} between plants and sow at {depth}. This spacing is crucial because it allows each plant enough room to develop properly and reduces competition for nutrients.
315
+
316
+ πŸ’§ **Water Management:**
317
+ Your {crop} will need {water_req}. The timing of watering is just as important as the amount - too much early on can cause root rot, while too little during grain formation reduces yield.
318
+
319
+ πŸ“ˆ **Why This Works:**
320
+ These recommendations are based on the plant's natural growth patterns. {crop.capitalize()} has specific nutritional and environmental needs during different growth stages, and following these guidelines maximizes your chances of a successful harvest.
321
+
322
+ Would you like me to explain any specific part of the cultivation process in more detail?"""
323
+
324
+ return response
325
+
326
+ def generate_fertilizer_response(self, crop: str, crop_data: dict) -> str:
327
+ """Generate fertilizer recommendation response"""
328
+ fertilizer_info = crop_data.get('fertilizer', {})
329
+ npk = fertilizer_info.get('npk', 'balanced NPK')
330
+ organic = fertilizer_info.get('organic', 'organic matter')
331
+ micronutrients = fertilizer_info.get('micronutrients', 'essential micronutrients')
332
+
333
+ response = f"""Excellent question about fertilizing {crop}! Proper nutrition is absolutely critical for good yields.
334
+
335
+ πŸ§ͺ **Primary Nutrition (NPK):**
336
+ For {crop}, I recommend {npk} per hectare. Here's why this ratio works:
337
+ - **Nitrogen (N)**: Promotes leaf growth and protein development
338
+ - **Phosphorus (P)**: Essential for root development and grain formation
339
+ - **Potassium (K)**: Improves disease resistance and grain quality
340
+
341
+ 🌿 **Organic Approach:**
342
+ Don't forget about {organic} - this improves soil structure and provides slow-release nutrients. Organic matter also feeds beneficial soil microorganisms that help your plants absorb nutrients more efficiently.
343
+
344
+ ⚑ **Micronutrients:**
345
+ {crop.capitalize()} also needs {micronutrients}. These might seem minor, but deficiencies can severely limit yield even when NPK levels are adequate.
346
+
347
+ πŸ’‘ **Application Strategy:**
348
+ Apply fertilizers in split doses rather than all at once. This prevents nutrient loss and ensures the plant gets nutrition when it needs it most during different growth stages.
349
+
350
+ **Timing is Everything:**
351
+ Early application supports vegetative growth, while later applications during flowering/grain filling stages directly impact your final yield.
352
+
353
+ Need specific timing recommendations for your growing season?"""
354
+
355
+ return response
356
+
357
+ def generate_pest_disease_response(self, crop: str, crop_data: dict, query: str) -> str:
358
+ """Generate pest/disease management response"""
359
+ diseases = crop_data.get('diseases', [])
360
+ pests = crop_data.get('pests', [])
361
+
362
+ if 'disease' in query.lower() and diseases:
363
+ main_disease = diseases[0] if diseases else {}
364
+ disease_name = main_disease.get('name', 'common diseases')
365
+ symptoms = main_disease.get('symptoms', 'various symptoms')
366
+ control = main_disease.get('control', 'appropriate treatment')
367
+
368
+ response = f"""I understand your concern about {crop} diseases. {disease_name} is indeed one of the most common issues farmers face.
369
+
370
+ πŸ” **What to Look For:**
371
+ {symptoms} - catching this early is crucial for effective management.
372
+
373
+ πŸ’Š **Treatment Approach:**
374
+ {control} is your best bet for control. But remember, prevention is always better than cure.
375
+
376
+ πŸ›‘οΈ **Prevention Strategy:**
377
+ - Ensure proper plant spacing for air circulation
378
+ - Avoid overhead watering when possible
379
+ - Remove and destroy infected plant material immediately
380
+ - Practice crop rotation to break disease cycles
381
+
382
+ 🌿 **Integrated Approach:**
383
+ Combine chemical treatments with cultural practices for best results. Healthy plants with good nutrition are naturally more resistant to diseases.
384
+
385
+ The key is regular monitoring - walk your fields weekly and check for early signs. Early detection means easier, cheaper, and more effective treatment."""
386
+
387
+ elif 'pest' in query.lower() and pests:
388
+ main_pest = pests[0] if pests else {}
389
+ pest_name = main_pest.get('name', 'common pests')
390
+ damage = main_pest.get('damage', 'plant damage')
391
+ control = main_pest.get('control', 'pest control measures')
392
+
393
+ response = f"""Pest management in {crop} is definitely important for protecting your investment. {pest_name} can cause significant {damage} if not managed properly.
394
+
395
+ 🎯 **Control Strategy:**
396
+ {control} - but let's talk about a comprehensive approach.
397
+
398
+ πŸ” **Monitoring:**
399
+ Regular field scouting is essential. Check plants weekly, especially during vulnerable growth stages.
400
+
401
+ 🌿 **Integrated Pest Management (IPM):**
402
+ 1. **Biological control**: Encourage beneficial insects
403
+ 2. **Cultural practices**: Proper spacing, sanitation
404
+ 3. **Chemical control**: Only when necessary and at right timing
405
+
406
+ πŸ’‘ **Pro Tip:**
407
+ Economic thresholds matter - not every pest requires immediate chemical intervention. Sometimes the cost of treatment exceeds the potential damage.
408
+
409
+ **Timing is Critical:**
410
+ Apply controls when pests are in their most vulnerable stage, not necessarily when you first see them."""
411
+
412
+ else:
413
+ response = f"""For {crop} protection, I recommend an integrated approach combining prevention, monitoring, and targeted treatment.
414
+
415
+ πŸ›‘οΈ **Prevention First:**
416
+ - Choose resistant varieties when available
417
+ - Maintain proper plant spacing and field sanitation
418
+ - Practice crop rotation to break pest/disease cycles
419
+
420
+ πŸ” **Regular Monitoring:**
421
+ Weekly field scouting helps catch problems early when they're easier and cheaper to manage.
422
+
423
+ ⚑ **Quick Response:**
424
+ When you do identify issues, act quickly but strategically. Consider economic thresholds and use targeted treatments rather than broad-spectrum approaches."""
425
+
426
+ return response
427
+
428
+ def generate_harvest_response(self, crop: str, crop_data: dict) -> str:
429
+ """Generate harvest timing and method response"""
430
+ harvest_info = crop_data.get('harvesting', {})
431
+ timing = harvest_info.get('time', 'appropriate maturity')
432
+ indicators = harvest_info.get('indicators', 'visual cues')
433
+ method = harvest_info.get('method', 'proper harvesting technique')
434
+ yield_expected = crop_data.get('yield', 'good yields')
435
+
436
+ response = f"""Timing your {crop} harvest correctly is crucial for maximizing both quantity and quality!
437
+
438
+ ⏰ **Perfect Timing:**
439
+ {crop.capitalize()} is typically ready for harvest {timing}. But don't just go by the calendar - the plant will tell you when it's ready.
440
+
441
+ πŸ‘€ **What to Look For:**
442
+ {indicators} - these are nature's signals that your crop has reached optimal maturity.
443
+
444
+ 🌾 **Harvesting Method:**
445
+ Use {method} for best results. The method you choose affects not just efficiency, but also grain quality and storage life.
446
+
447
+ πŸ“Š **Expected Results:**
448
+ With proper cultivation and timing, you can expect {yield_expected} under good conditions.
449
+
450
+ πŸ’‘ **Pro Tips:**
451
+ - Harvest during dry weather when possible
452
+ - Early morning harvesting often gives better quality
453
+ - Don't delay once the crop is ready - overripe crops can lose quality quickly
454
+ - Proper post-harvest handling is just as important as growing
455
+
456
+ πŸͺ **Post-Harvest:**
457
+ Quick drying and proper storage will protect your hard work and maintain market value.
458
+
459
+ The key is balancing maximum maturity with optimal quality - harvest too early and you lose yield, too late and you lose quality."""
460
+
461
+ return response
462
+
463
+ def generate_general_crop_response(self, crop: str, crop_data: dict, query: str) -> str:
464
+ """Generate general crop information response"""
465
+ season = crop_data.get('season', 'growing season')
466
+ climate = crop_data.get('climate', 'suitable climate')
467
+ uses = crop_data.get('market_uses', ['food production'])
468
+
469
+ response = f"""Let me share some key insights about {crop} cultivation that might help you.
470
+
471
+ 🌾 **Overview:**
472
+ {crop.capitalize()} is typically grown during {season} and thrives in {climate}. It's a valuable crop with multiple uses including {', '.join(uses[:3]) if isinstance(uses, list) else uses}.
473
+
474
+ πŸ“Š **Key Success Factors:**
475
+ 1. **Timing**: Planting at the right time for your region
476
+ 2. **Soil preparation**: Proper soil conditions are fundamental
477
+ 3. **Water management**: Balanced irrigation throughout the season
478
+ 4. **Nutrition**: Adequate fertilization for healthy growth
479
+ 5. **Protection**: Monitoring and managing pests/diseases
480
+
481
+ πŸ’Ό **Market Potential:**
482
+ {crop.capitalize()} has good market demand, making it a commercially viable option when grown properly.
483
+
484
+ 🎯 **My Recommendation:**
485
+ Start with small test plots if you're new to {crop} cultivation. This lets you learn the crop's behavior in your specific conditions before scaling up.
486
+
487
+ Would you like me to dive deeper into any specific aspect of {crop} production?"""
488
+
489
+ return response
490
+
491
+ def generate_general_farming_response(self, query: str, context: str) -> str:
492
+ """Generate general farming advice response"""
493
+ response = f"""That's a great farming question! Based on current agricultural best practices, here's my advice:
494
+
495
+ πŸ’‘ **General Recommendations:**
496
+ Agriculture success comes from understanding your local conditions and adapting proven techniques to your specific situation.
497
+
498
+ 🌱 **Key Principles:**
499
+ - Soil health is the foundation of everything
500
+ - Prevention is more cost-effective than treatment
501
+ - Regular monitoring helps catch issues early
502
+ - Sustainable practices ensure long-term success
503
+
504
+ πŸ“ˆ **Next Steps:**
505
+ I'd recommend consulting with local agricultural extension services for region-specific advice, as local conditions can significantly impact the best approaches.
506
+
507
+ Would you like me to elaborate on any specific aspect of this topic?"""
508
+
509
+ return response
510
+
511
+ def get_user_name(self, message):
512
+ name_patterns = [
513
+ r"my name is (\w+)",
514
+ r"i'm (\w+)",
515
+ r"i am (\w+)",
516
+ r"call me (\w+)"
517
+ ]
518
+
519
+ for pattern in name_patterns:
520
+ match = re.search(pattern, message.lower())
521
+ if match:
522
+ self.user_name = match.group(1).capitalize()
523
+ return f"Nice to meet you, {self.user_name}! How can I assist you with your farming needs?"
524
+ return None
525
+
526
+ def process_message(self, message: str) -> str:
527
+ """Main method to process user messages and generate AI responses"""
528
+ # Check if the user is introducing themselves
529
+ name_response = self.get_user_name(message)
530
+ if name_response:
531
+ return name_response
532
+
533
+ # Search for relevant information in our knowledge base
534
+ search_results = self.semantic_search(message, top_k=3)
535
+
536
+ # Extract context from search results
537
+ context = ""
538
+ if search_results:
539
+ context_parts = []
540
+ for result in search_results:
541
+ if result['score'] > 0.3: # Relevance threshold
542
+ context_parts.append(result['item']['content'])
543
+ context = " ".join(context_parts)
544
+
545
+ # Generate AI response using context
546
+ ai_response = self.generate_ai_response(message, context)
547
+
548
+ if ai_response and len(ai_response.strip()) > 20:
549
+ return ai_response
550
+ else:
551
+ # Final fallback
552
+ return self.get_fallback_response(message)
553
+
554
+ def get_fallback_response(self, query: str) -> str:
555
+ """Provide fallback response when no specific information is found"""
556
+ query_lower = query.lower()
557
+
558
+ if any(word in query_lower for word in ['crop', 'plant', 'grow']):
559
+ available_crops = list(self.agricultural_data.get('crops', {}).keys())
560
+ return f"""I'd be happy to help you with crop cultivation! I have detailed information about {', '.join(available_crops)}.
561
+
562
+ These crops have different requirements for soil, climate, and management practices. Each one offers unique opportunities and challenges.
563
+
564
+ Could you let me know which specific crop you're interested in, or would you like me to recommend crops suitable for your conditions?"""
565
+
566
+ elif any(word in query_lower for word in ['pest', 'insect', 'bug']):
567
+ return """Pest management is crucial for successful farming! Here's my approach:
568
+
569
+ 🎯 **Integrated Pest Management (IPM):**
570
+ The most effective strategy combines multiple approaches rather than relying solely on pesticides.
571
+
572
+ πŸ” **Early Detection:**
573
+ Regular field scouting is your best tool - catching problems early makes them much easier and cheaper to manage.
574
+
575
+ 🌿 **Natural Controls:**
576
+ Encourage beneficial insects, practice crop rotation, and maintain healthy soil to build natural resistance.
577
+
578
+ ⚑ **Strategic Intervention:**
579
+ When chemical control is needed, timing and targeted application are key to effectiveness.
580
+
581
+ Which specific pest are you dealing with? I can provide more targeted advice."""
582
+
583
+ elif any(word in query_lower for word in ['disease', 'fungus', 'infection']):
584
+ return """Plant diseases can significantly impact your harvest, but they're manageable with the right approach:
585
+
586
+ πŸ›‘οΈ **Prevention Strategy:**
587
+ - Choose disease-resistant varieties when available
588
+ - Ensure proper plant spacing for air circulation
589
+ - Practice crop rotation to break disease cycles
590
+ - Maintain soil health for stronger plants
591
+
592
+ πŸ” **Early Recognition:**
593
+ Learn to identify early symptoms - quick action is always more effective than waiting.
594
+
595
+ πŸ’Š **Treatment Options:**
596
+ Combine cultural practices with appropriate fungicides or bactericides when necessary.
597
+
598
+ Which crop disease are you concerned about? I can provide specific guidance."""
599
+
600
+ else:
601
+ return """I'm here to help with all aspects of modern agriculture! Whether you're dealing with:
602
+
603
+ 🌱 **Crop selection and cultivation**
604
+ 🌍 **Soil health and fertilization**
605
+ πŸ› **Pest and disease management**
606
+ β›… **Weather-related challenges**
607
+ πŸ“ˆ **Yield optimization strategies**
608
+
609
+ Each farming situation is unique, and the best approach depends on your specific conditions, resources, and goals.
610
+
611
+ What specific agricultural challenge can I help you tackle today?"""
612
+
613
+ # Initialize the bot
614
+ bot = AgriBot()
615
+
616
+ def chat_response(message, history):
617
+ """Generate response for Gradio chat interface"""
618
+ if not message.strip():
619
+ return "Please ask me something about agriculture!"
620
+
621
+ response = bot.process_message(message)
622
+ return response
623
+
624
+ def greet():
625
+ return "Hello! I'm AgriBot, your AI-powered agricultural assistant. I can help you with crop cultivation, pest management, disease control, fertilizers, and general farming advice. What would you like to know about farming today?"
626
+
627
+ # Create Gradio interface
628
+ def create_interface():
629
+ with gr.Blocks(
630
+ title="🌾 AgriBot - AI Agricultural Assistant",
631
+ theme=gr.themes.Base(
632
+ primary_hue="green",
633
+ secondary_hue="emerald",
634
+ neutral_hue="gray",
635
+ font=[gr.themes.GoogleFont("Inter"), "Arial", "sans-serif"]
636
+ ),
637
+ css="""
638
+ /* Main Container Styling */
639
+ .gradio-container {
640
+ max-width: 1400px !important;
641
+ margin: 0 auto !important;
642
+ padding: 20px !important;
643
+ background: linear-gradient(135deg, #f0f8f0 0%, #e8f5e8 100%) !important;
644
+ }
645
+
646
+ /* Header Styling */
647
+ .main-header {
648
+ text-align: center;
649
+ padding: 30px 20px;
650
+ background: linear-gradient(135deg, #2d5016 0%, #4a7c3c 50%, #5d8b4a 100%);
651
+ border-radius: 15px;
652
+ margin-bottom: 25px;
653
+ color: white !important;
654
+ box-shadow: 0 8px 32px rgba(45, 80, 22, 0.3);
655
+ border: 1px solid rgba(255, 255, 255, 0.2);
656
+ }
657
+
658
+ .main-header h1 {
659
+ color: white !important;
660
+ font-size: 2.5rem !important;
661
+ font-weight: 700 !important;
662
+ margin-bottom: 10px !important;
663
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.3) !important;
664
+ }
665
+
666
+ .main-header p {
667
+ color: #e8f5e8 !important;
668
+ font-size: 1.2rem !important;
669
+ margin: 0 !important;
670
+ font-weight: 400 !important;
671
+ }
672
+
673
+ /* Feature Cards */
674
+ .feature-grid {
675
+ display: grid;
676
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
677
+ gap: 20px;
678
+ margin-bottom: 25px;
679
+ }
680
+
681
+ .feature-card {
682
+ background: white !important;
683
+ padding: 25px !important;
684
+ border-radius: 12px !important;
685
+ border-left: 5px solid #4CAF50 !important;
686
+ box-shadow: 0 4px 15px rgba(0,0,0,0.1) !important;
687
+ transition: transform 0.3s ease, box-shadow 0.3s ease !important;
688
+ color: #2d5016 !important;
689
+ }
690
+
691
+ .feature-card:hover {
692
+ transform: translateY(-5px) !important;
693
+ box-shadow: 0 8px 25px rgba(0,0,0,0.15) !important;
694
+ }
695
+
696
+ .feature-card h3 {
697
+ color: #2d5016 !important;
698
+ font-size: 1.3rem !important;
699
+ font-weight: 600 !important;
700
+ margin-bottom: 10px !important;
701
+ }
702
+
703
+ .feature-card p {
704
+ color: #4a7c3c !important;
705
+ font-size: 1rem !important;
706
+ line-height: 1.5 !important;
707
+ margin: 0 !important;
708
+ }
709
+
710
+ /* Chat Container */
711
+ .chat-container {
712
+ background: white !important;
713
+ border-radius: 15px !important;
714
+ padding: 25px !important;
715
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1) !important;
716
+ margin-bottom: 20px !important;
717
+ }
718
+
719
+ /* Chatbot Styling */
720
+ .chatbot-container {
721
+ border: 2px solid #e8f5e8 !important;
722
+ border-radius: 12px !important;
723
+ background: #fafffe !important;
724
+ }
725
+
726
+ /* Override Gradio's default message styling */
727
+ .chatbot .message-wrap {
728
+ background: transparent !important;
729
+ }
730
+
731
+ .chatbot .message.user {
732
+ background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%) !important;
733
+ color: #0d47a1 !important;
734
+ border: 1px solid #90caf9 !important;
735
+ margin-left: 15% !important;
736
+ padding: 15px 20px !important;
737
+ border-radius: 15px 15px 5px 15px !important;
738
+ box-shadow: 0 2px 8px rgba(13, 71, 161, 0.2) !important;
739
+ font-weight: 500 !important;
740
+ }
741
+
742
+ .chatbot .message.bot {
743
+ background: linear-gradient(135deg, #e8f5e8 0%, #c8e6c9 100%) !important;
744
+ color: #1b5e20 !important;
745
+ border: 1px solid #a5d6a7 !important;
746
+ margin-right: 15% !important;
747
+ padding: 15px 20px !important;
748
+ border-radius: 15px 15px 15px 5px !important;
749
+ box-shadow: 0 2px 8px rgba(27, 94, 32, 0.2) !important;
750
+ font-weight: 500 !important;
751
+ }
752
+
753
+ /* Force text color in chat messages */
754
+ .chatbot .message.user * {
755
+ color: #0d47a1 !important;
756
+ }
757
+
758
+ .chatbot .message.bot * {
759
+ color: #1b5e20 !important;
760
+ }
761
+
762
+ /* Ensure chat text is always visible */
763
+ .gradio-chatbot .chatbot .message {
764
+ color: inherit !important;
765
+ }
766
+
767
+ .gradio-chatbot .chatbot .message p {
768
+ color: inherit !important;
769
+ margin: 5px 0 !important;
770
+ line-height: 1.5 !important;
771
+ }
772
+
773
+ /* User message styling */
774
+ .gradio-chatbot .user {
775
+ background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%) !important;
776
+ color: #0d47a1 !important;
777
+ border: 1px solid #90caf9 !important;
778
+ border-radius: 15px 15px 5px 15px !important;
779
+ margin-left: 15% !important;
780
+ margin-right: 5% !important;
781
+ }
782
+
783
+ /* Bot message styling */
784
+ .gradio-chatbot .bot {
785
+ background: linear-gradient(135deg, #e8f5e8 0%, #c8e6c9 100%) !important;
786
+ color: #1b5e20 !important;
787
+ border: 1px solid #a5d6a7 !important;
788
+ border-radius: 15px 15px 15px 5px !important;
789
+ margin-right: 15% !important;
790
+ margin-left: 5% !important;
791
+ }
792
+
793
+ /* Input Styling */
794
+ .input-container {
795
+ background: white !important;
796
+ border-radius: 12px !important;
797
+ border: 2px solid #e8f5e8 !important;
798
+ padding: 5px !important;
799
+ margin-top: 15px !important;
800
+ }
801
+
802
+ .input-container:focus-within {
803
+ border-color: #4CAF50 !important;
804
+ box-shadow: 0 0 10px rgba(76, 175, 80, 0.2) !important;
805
+ }
806
+
807
+ /* Input text styling */
808
+ .input-container textarea,
809
+ .input-container input {
810
+ color: #2d5016 !important;
811
+ background: white !important;
812
+ border: none !important;
813
+ font-size: 1rem !important;
814
+ font-weight: 500 !important;
815
+ }
816
+
817
+ .input-container textarea::placeholder,
818
+ .input-container input::placeholder {
819
+ color: #6b7280 !important;
820
+ opacity: 0.8 !important;
821
+ }
822
+
823
+ /* Override any Gradio input styling */
824
+ .gradio-textbox {
825
+ background: white !important;
826
+ }
827
+
828
+ .gradio-textbox textarea {
829
+ color: #2d5016 !important;
830
+ background: white !important;
831
+ border: 2px solid #e8f5e8 !important;
832
+ border-radius: 8px !important;
833
+ padding: 12px !important;
834
+ font-size: 1rem !important;
835
+ }
836
+
837
+ .gradio-textbox textarea:focus {
838
+ border-color: #4CAF50 !important;
839
+ box-shadow: 0 0 10px rgba(76, 175, 80, 0.2) !important;
840
+ outline: none !important;
841
+ }
842
+
843
+ /* Button Styling */
844
+ .btn-primary {
845
+ background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%) !important;
846
+ color: white !important;
847
+ border: none !important;
848
+ border-radius: 8px !important;
849
+ padding: 12px 24px !important;
850
+ font-weight: 600 !important;
851
+ font-size: 1rem !important;
852
+ transition: all 0.3s ease !important;
853
+ box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3) !important;
854
+ }
855
+
856
+ .btn-primary:hover {
857
+ background: linear-gradient(135deg, #45a049 0%, #3d8b40 100%) !important;
858
+ transform: translateY(-2px) !important;
859
+ box-shadow: 0 6px 20px rgba(76, 175, 80, 0.4) !important;
860
+ }
861
+
862
+ .btn-secondary {
863
+ background: linear-gradient(135deg, #6c757d 0%, #5a6268 100%) !important;
864
+ color: white !important;
865
+ border: none !important;
866
+ border-radius: 8px !important;
867
+ padding: 12px 24px !important;
868
+ font-weight: 600 !important;
869
+ transition: all 0.3s ease !important;
870
+ }
871
+
872
+ .btn-secondary:hover {
873
+ background: linear-gradient(135deg, #5a6268 0%, #495057 100%) !important;
874
+ transform: translateY(-2px) !important;
875
+ }
876
+
877
+ /* Sidebar Styling */
878
+ .sidebar {
879
+ background: white !important;
880
+ border-radius: 15px !important;
881
+ padding: 25px !important;
882
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1) !important;
883
+ height: fit-content !important;
884
+ }
885
+
886
+ .sidebar h3 {
887
+ color: #2d5016 !important;
888
+ font-size: 1.4rem !important;
889
+ font-weight: 600 !important;
890
+ margin-bottom: 15px !important;
891
+ padding-bottom: 10px !important;
892
+ border-bottom: 2px solid #e8f5e8 !important;
893
+ }
894
+
895
+ .sidebar ul {
896
+ list-style: none !important;
897
+ padding: 0 !important;
898
+ margin: 0 !important;
899
+ }
900
+
901
+ .sidebar li {
902
+ color: #4a7c3c !important;
903
+ padding: 8px 0 !important;
904
+ border-bottom: 1px solid #f0f8f0 !important;
905
+ font-size: 0.95rem !important;
906
+ line-height: 1.4 !important;
907
+ }
908
+
909
+ .sidebar strong {
910
+ color: #2d5016 !important;
911
+ font-weight: 600 !important;
912
+ }
913
+
914
+ /* Examples Section */
915
+ .examples-section {
916
+ background: #f8fffe !important;
917
+ padding: 20px !important;
918
+ border-radius: 10px !important;
919
+ margin-top: 20px !important;
920
+ border: 1px solid #e8f5e8 !important;
921
+ }
922
+
923
+ /* Footer Styling */
924
+ .footer {
925
+ text-align: center;
926
+ padding: 25px;
927
+ background: linear-gradient(135deg, #2d5016 0%, #4a7c3c 100%);
928
+ border-radius: 15px;
929
+ margin-top: 30px;
930
+ color: white !important;
931
+ box-shadow: 0 8px 32px rgba(45, 80, 22, 0.3);
932
+ }
933
+
934
+ .footer p {
935
+ color: white !important;
936
+ margin: 5px 0 !important;
937
+ font-size: 1rem !important;
938
+ }
939
+
940
+ .footer strong {
941
+ color: #e8f5e8 !important;
942
+ font-size: 1.2rem !important;
943
+ }
944
+
945
+ /* Responsive Design */
946
+ @media (max-width: 768px) {
947
+ .gradio-container {
948
+ padding: 10px !important;
949
+ }
950
+
951
+ .main-header {
952
+ padding: 20px 15px !important;
953
+ }
954
+
955
+ .main-header h1 {
956
+ font-size: 2rem !important;
957
+ }
958
+
959
+ .feature-grid {
960
+ grid-template-columns: 1fr !important;
961
+ gap: 15px !important;
962
+ }
963
+
964
+ .chat-container, .sidebar {
965
+ padding: 15px !important;
966
+ }
967
+
968
+ .feature-card {
969
+ padding: 20px !important;
970
+ }
971
+ }
972
+
973
+ /* Text Visibility Fixes */
974
+ .gr-textbox textarea {
975
+ color: #2d5016 !important;
976
+ background: white !important;
977
+ }
978
+
979
+ .gr-textbox label {
980
+ color: #2d5016 !important;
981
+ font-weight: 600 !important;
982
+ }
983
+
984
+ /* Loading Animation */
985
+ .loading {
986
+ display: inline-block;
987
+ width: 20px;
988
+ height: 20px;
989
+ border: 3px solid #e8f5e8;
990
+ border-radius: 50%;
991
+ border-top-color: #4CAF50;
992
+ animation: spin 1s ease-in-out infinite;
993
+ }
994
+
995
+ @keyframes spin {
996
+ to { transform: rotate(360deg); }
997
+ }
998
+ """
999
+ ) as iface:
1000
+
1001
+ # Header
1002
+ gr.HTML("""
1003
+ <div class="main-header">
1004
+ <h1>🌾 AgriBot - AI Agricultural Assistant</h1>
1005
+ <p>Expert farming guidance powered by artificial intelligence and comprehensive agricultural data</p>
1006
+ </div>
1007
+ """)
1008
+
1009
+ # Feature highlights
1010
+ gr.HTML("""
1011
+ <div class="feature-grid">
1012
+ <div class="feature-card">
1013
+ <h3>🧠 AI-Powered Intelligence</h3>
1014
+ <p>Advanced AI models process your questions and provide conversational, expert-level agricultural advice tailored to your specific needs.</p>
1015
+ </div>
1016
+ <div class="feature-card">
1017
+ <h3>🌱 Comprehensive Database</h3>
1018
+ <p>Extensive knowledge base covering crops, diseases, pests, fertilizers, soil management, and modern farming techniques.</p>
1019
+ </div>
1020
+ <div class="feature-card">
1021
+ <h3>πŸ’‘ Professional Guidance</h3>
1022
+ <p>Get practical, actionable advice from cultivation to harvest, including organic farming, IPM, and sustainable practices.</p>
1023
+ </div>
1024
+ </div>
1025
+ """)
1026
+
1027
+ # Main chat area
1028
+ with gr.Row(equal_height=True):
1029
+ with gr.Column(scale=7):
1030
+ gr.HTML('<div class="chat-container">')
1031
+
1032
+ chatbot = gr.Chatbot(
1033
+ value=[(None, greet())],
1034
+ height=520,
1035
+ label="πŸ’¬ Chat with AgriBot",
1036
+ show_label=True,
1037
+ container=True,
1038
+ bubble_full_width=False,
1039
+ avatar_images=(
1040
+ "https://cdn-icons-png.flaticon.com/512/1077/1077012.png", # User
1041
+ "https://cdn-icons-png.flaticon.com/512/1998/1998667.png" # Bot
1042
+ ),
1043
+ elem_classes=["chatbot-container"]
1044
+ )
1045
+
1046
+ with gr.Row():
1047
+ msg = gr.Textbox(
1048
+ label="🌾 Ask me anything about agriculture...",
1049
+ placeholder="Example: 'How to grow wheat in clay soil?' or 'Best fertilizer for rice cultivation?' or 'Organic pest control methods?'",
1050
+ lines=2,
1051
+ max_lines=4,
1052
+ scale=4,
1053
+ elem_classes=["input-container"]
1054
+ )
1055
+
1056
+ with gr.Row():
1057
+ with gr.Column(scale=2):
1058
+ submit_btn = gr.Button("πŸš€ Send Message", variant="primary", elem_classes=["btn-primary"])
1059
+ with gr.Column(scale=1):
1060
+ clear_btn = gr.Button("πŸ—‘οΈ Clear Chat", variant="secondary", elem_classes=["btn-secondary"])
1061
+
1062
+ gr.HTML('</div>')
1063
+
1064
+ with gr.Column(scale=3):
1065
+ gr.HTML("""
1066
+ <div class="sidebar">
1067
+ <h3>🌾 Agricultural Topics</h3>
1068
+ <ul>
1069
+ <li><strong>🌱 Crops:</strong> Rice, Wheat, Corn, Tomato, Potato</li>
1070
+ <li><strong>🌱 Cultivation:</strong> Planting, Growing, Harvesting</li>
1071
+ <li><strong>πŸ§ͺ Nutrition:</strong> NPK Fertilizers, Organic Matter</li>
1072
+ <li><strong>πŸ›‘οΈ Protection:</strong> Pest Control, Disease Management</li>
1073
+ <li><strong>βš™οΈ Techniques:</strong> Organic Farming, IPM, Crop Rotation</li>
1074
+ <li><strong>🌍 Soil:</strong> pH Management, Soil Health</li>
1075
+ <li><strong>β›… Weather:</strong> Climate Adaptation, Seasonal Advice</li>
1076
+ </ul>
1077
+
1078
+ <div class="examples-section">
1079
+ <h3>πŸ’¬ Try These Questions</h3>
1080
+ <ul>
1081
+ <li>"How to cultivate wheat in winter?"</li>
1082
+ <li>"Rice fertilizer requirements and timing"</li>
1083
+ <li>"Organic methods for tomato pest control"</li>
1084
+ <li>"Soil preparation for corn planting"</li>
1085
+ <li>"Disease management in potato crops"</li>
1086
+ <li>"Best practices for crop rotation"</li>
1087
+ </ul>
1088
+ </div>
1089
+
1090
+ <div style="margin-top: 20px; padding: 15px; background: #f0f8f0; border-radius: 8px; text-align: center;">
1091
+ <p style="margin: 0; color: #2d5016; font-weight: 600;">πŸ€– AI Status</p>
1092
+ <p style="margin: 5px 0 0 0; color: #4a7c3c; font-size: 0.9rem;">Ready to help!</p>
1093
+ </div>
1094
+ </div>
1095
+ """)
1096
+
1097
+ # Quick action buttons
1098
+ gr.HTML("""
1099
+ <div style="margin: 20px 0; text-align: center;">
1100
+ <h3 style="color: #2d5016; margin-bottom: 15px;">πŸš€ Quick Start Topics</h3>
1101
+ </div>
1102
+ """)
1103
+
1104
+ with gr.Row():
1105
+ crop_btn = gr.Button("🌾 Crop Cultivation", elem_classes=["btn-primary"])
1106
+ pest_btn = gr.Button("πŸ› Pest Management", elem_classes=["btn-primary"])
1107
+ disease_btn = gr.Button("🦠 Disease Control", elem_classes=["btn-primary"])
1108
+ fertilizer_btn = gr.Button("πŸ§ͺ Fertilizers", elem_classes=["btn-primary"])
1109
+
1110
+ # Function to handle chat
1111
+ def respond(message, chat_history):
1112
+ if not message.strip():
1113
+ return chat_history, ""
1114
+
1115
+ response = bot.process_message(message)
1116
+ chat_history.append((message, response))
1117
+ return chat_history, ""
1118
+
1119
+ # Function to set quick questions
1120
+ def set_quick_question(question):
1121
+ return question
1122
+
1123
+ # Event handlers for main chat
1124
+ submit_btn.click(respond, [msg, chatbot], [chatbot, msg])
1125
+ msg.submit(respond, [msg, chatbot], [chatbot, msg])
1126
+ clear_btn.click(lambda: ([(None, greet())], ""), outputs=[chatbot, msg])
1127
+
1128
+ # Quick action button handlers
1129
+ crop_btn.click(
1130
+ set_quick_question,
1131
+ inputs=gr.State("Tell me about crop cultivation techniques and best practices for growing healthy crops"),
1132
+ outputs=msg
1133
+ )
1134
+
1135
+ pest_btn.click(
1136
+ set_quick_question,
1137
+ inputs=gr.State("How can I manage pests in my crops using organic and sustainable methods?"),
1138
+ outputs=msg
1139
+ )
1140
+
1141
+ disease_btn.click(
1142
+ set_quick_question,
1143
+ inputs=gr.State("What are effective disease control strategies for common crop diseases?"),
1144
+ outputs=msg
1145
+ )
1146
+
1147
+ fertilizer_btn.click(
1148
+ set_quick_question,
1149
+ inputs=gr.State("What fertilizers should I use for optimal crop growth and when to apply them?"),
1150
+ outputs=msg
1151
+ )
1152
+
1153
+ # Footer
1154
+ gr.HTML("""
1155
+ <div class="footer">
1156
+ <p><strong>🌾 AgriBot - Your AI Agricultural Consultant</strong></p>
1157
+ <p>Powered by advanced AI β€’ Comprehensive agricultural database β€’ Expert farming guidance</p>
1158
+ <p>Β© 2025 AgriBot | Helping farmers grow smarter with AI technology</p>
1159
+ </div>
1160
+ """)
1161
+
1162
+ return iface
1163
+
1164
+ # Create and launch the interface
1165
+ if __name__ == "__main__":
1166
+ interface = create_interface()
1167
+ interface.launch(
1168
+ share=True,
1169
+ server_name="0.0.0.0",
1170
+ server_port=7860,
1171
+ show_api=False
1172
+ )