github-actions[bot] commited on
Commit
58726c2
·
1 Parent(s): c6acc20

Deploy from GitHub: e41cf0cdffa82676b7c2034ffdca57d930b5e475

Browse files
app/routers/disease.py CHANGED
@@ -17,7 +17,10 @@ def _looks_agri_product(title: str | None, source: str | None) -> bool:
17
  text = f"{title or ''} {source or ''}".lower()
18
  agri_keywords = [
19
  "fungicide", "pesticide", "insecticide", "herbicide", "fertilizer",
20
- "agri", "agriculture", "crop", "plant", "seed", "biofungicide"
 
 
 
21
  ]
22
  bad_keywords = [
23
  "amplifier", "speaker", "audio", "guitar", "home", "quilt", "comforter"
@@ -38,11 +41,19 @@ async def process_disease(request: DiseaseRequest):
38
  seen_links = set()
39
  for item in extracted_products:
40
  product_name = (item.get("name") or "").strip() if isinstance(item, dict) else ""
 
41
  if not product_name:
42
  continue
43
 
44
- # Enrich search query so generic names do not fetch irrelevant products.
45
- search_query = f"{product_name} agricultural fungicide pesticide crop treatment india"
 
 
 
 
 
 
 
46
  search_results = search_shopping(search_query)
47
  shopping = search_results.get('shopping', [])
48
 
 
17
  text = f"{title or ''} {source or ''}".lower()
18
  agri_keywords = [
19
  "fungicide", "pesticide", "insecticide", "herbicide", "fertilizer",
20
+ "agri", "agriculture", "crop", "plant", "seed", "biofungicide",
21
+ "garden", "horticulture", "foliar", "micronutrient", "nutrient",
22
+ "calcium", "magnesium", "zinc", "boron", "sulfate", "sulphate",
23
+ "npk", "chelate", "soil conditioner", "plant tonic"
24
  ]
25
  bad_keywords = [
26
  "amplifier", "speaker", "audio", "guitar", "home", "quilt", "comforter"
 
41
  seen_links = set()
42
  for item in extracted_products:
43
  product_name = (item.get("name") or "").strip() if isinstance(item, dict) else ""
44
+ category = (item.get("category") or "other").strip().lower() if isinstance(item, dict) else "other"
45
  if not product_name:
46
  continue
47
 
48
+ # Use category-aware query; previous fungicide-only bias caused misses for nutrient disorders.
49
+ if category == "nutrient":
50
+ suffix = "agriculture plant nutrient foliar spray india"
51
+ elif category in ("fungicide", "pesticide", "bio"):
52
+ suffix = f"agriculture {category} crop treatment india"
53
+ else:
54
+ suffix = "agriculture crop plant treatment india"
55
+
56
+ search_query = f"{product_name} {suffix}"
57
  search_results = search_shopping(search_query)
58
  shopping = search_results.get('shopping', [])
59
 
app/services/llm_service.py CHANGED
@@ -1,5 +1,6 @@
1
  import json
2
  import base64
 
3
  from app.config import settings
4
 
5
  try:
@@ -76,11 +77,45 @@ def detect_disease(image_data: str, query: str = ""):
76
 
77
 
78
  def extract_agri_products(detection_text: str):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  prompt = (
80
- "From the disease analysis below, extract only AGRICULTURAL products that a farmer can buy "
81
- "for treatment (fungicides, pesticides, bio-products, etc.). "
 
82
  "Return STRICT JSON only with this format: "
83
- "{\"products\": [{\"name\": \"...\", \"category\": \"fungicide|pesticide|bio|other\"}]}. "
84
  "Do not include non-agriculture items. If none are present return {\"products\": []}. "
85
  f"Analysis: {detection_text}"
86
  )
@@ -88,7 +123,8 @@ def extract_agri_products(detection_text: str):
88
  oai = _get_openai_client()
89
  completion = oai.chat.completions.create(
90
  model="gpt-4o-mini",
91
- temperature=0.1,
 
92
  messages=[{"role": "user", "content": prompt}],
93
  )
94
  extraction_text = completion.choices[0].message.content or ""
@@ -96,9 +132,12 @@ def extract_agri_products(detection_text: str):
96
  extraction_text = _clean_fenced_json(extraction_text)
97
  try:
98
  parsed = json.loads(extraction_text)
99
- return parsed.get("products", []) if isinstance(parsed, dict) else []
 
 
 
100
  except json.JSONDecodeError:
101
- return []
102
 
103
  def chat_bot(query: str, image_data: bytes = None):
104
  system_instruction = (
 
1
  import json
2
  import base64
3
+ import re
4
  from app.config import settings
5
 
6
  try:
 
77
 
78
 
79
  def extract_agri_products(detection_text: str):
80
+ def _heuristic_product_candidates(text: str):
81
+ # Fallback parser from chemical solution sections when model extraction is empty/invalid.
82
+ candidates = []
83
+ seen = set()
84
+
85
+ patterns = [
86
+ r"active\s+ingredient\(s\)\s*:\s*(.+)",
87
+ r"product\s+type\s*:\s*(.+)",
88
+ r"recommended\s+products?\s*:\s*(.+)",
89
+ ]
90
+
91
+ for line in (text or "").splitlines():
92
+ clean = line.strip(" -•*\t")
93
+ if not clean:
94
+ continue
95
+
96
+ for p in patterns:
97
+ m = re.search(p, clean, flags=re.IGNORECASE)
98
+ if not m:
99
+ continue
100
+ values = re.split(r",|/|\band\b", m.group(1), flags=re.IGNORECASE)
101
+ for value in values:
102
+ name = value.strip(" .:;-")
103
+ if len(name) < 3:
104
+ continue
105
+ key = name.lower()
106
+ if key in seen:
107
+ continue
108
+ seen.add(key)
109
+ candidates.append({"name": name, "category": "other"})
110
+
111
+ return candidates[:8]
112
+
113
  prompt = (
114
+ "From the disease analysis below, extract only AGRICULTURAL treatment inputs that a farmer can buy "
115
+ "(fungicides, pesticides, bio-products, micronutrients, plant supplements, soil amendments, etc.). "
116
+ "Prefer active ingredients and practical market search terms. "
117
  "Return STRICT JSON only with this format: "
118
+ "{\"products\": [{\"name\": \"...\", \"category\": \"fungicide|pesticide|bio|nutrient|other\"}]}. "
119
  "Do not include non-agriculture items. If none are present return {\"products\": []}. "
120
  f"Analysis: {detection_text}"
121
  )
 
123
  oai = _get_openai_client()
124
  completion = oai.chat.completions.create(
125
  model="gpt-4o-mini",
126
+ temperature=0,
127
+ response_format={"type": "json_object"},
128
  messages=[{"role": "user", "content": prompt}],
129
  )
130
  extraction_text = completion.choices[0].message.content or ""
 
132
  extraction_text = _clean_fenced_json(extraction_text)
133
  try:
134
  parsed = json.loads(extraction_text)
135
+ products = parsed.get("products", []) if isinstance(parsed, dict) else []
136
+ if isinstance(products, list) and products:
137
+ return products
138
+ return _heuristic_product_candidates(detection_text)
139
  except json.JSONDecodeError:
140
+ return _heuristic_product_candidates(detection_text)
141
 
142
  def chat_bot(query: str, image_data: bytes = None):
143
  system_instruction = (