Spaces:
Running on Zero
Running on Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -137,55 +137,87 @@ def remove_repeated_sentences(text: str) -> str:
|
|
| 137 |
unique_sentences.append(sentence)
|
| 138 |
return " ".join(unique_sentences)
|
| 139 |
|
| 140 |
-
def clean_agri_output(raw_text: str) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
if not raw_text:
|
| 142 |
return ""
|
| 143 |
|
| 144 |
text = raw_text.strip()
|
| 145 |
|
|
|
|
| 146 |
text = re.sub(
|
| 147 |
-
r'(?:Context\s*:?\s*)?(?:Region|Owner|Farm|Season|Soil|Severity|Source
|
| 148 |
'', text, flags=re.IGNORECASE
|
| 149 |
)
|
| 150 |
text = re.sub(r'\bContext\s*:?\s*', '', text, flags=re.IGNORECASE)
|
| 151 |
text = re.sub(r'https?://\S+|\[.*?\]\(.*?\)', '', text)
|
| 152 |
text = re.sub(r"<\|.*?\|>", "", text)
|
| 153 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
recommendation_match = re.search(
|
| 155 |
-
r"(?:Recommended Action|Recommendation)\s*:\s*(.*?)(?=\n\s*(?:
|
| 156 |
-
text,
|
| 157 |
-
flags=re.IGNORECASE | re.DOTALL,
|
| 158 |
)
|
| 159 |
-
recommendation = recommendation_match.group(1).strip() if recommendation_match else ""
|
| 160 |
-
|
| 161 |
explanation_match = re.search(
|
| 162 |
r"Explanation\s*:\s*(.*?)(?=\n\s*(?:Problem|Possible Cause|Recommended Action|Recommendation)\s*:|\Z)",
|
| 163 |
-
text,
|
| 164 |
-
flags=re.IGNORECASE | re.DOTALL,
|
| 165 |
)
|
| 166 |
-
explanation = explanation_match.group(1).strip() if explanation_match else ""
|
| 167 |
|
| 168 |
-
if
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
text,
|
| 173 |
-
flags=re.IGNORECASE,
|
| 174 |
-
)
|
| 175 |
-
recommendation = re.split(r"\n#+\s*|\nContext:|\nExplanation:|\bRegion=", cleaned)[0].strip()
|
| 176 |
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
|
|
|
| 180 |
|
| 181 |
recommendation = re.sub(r"\s+", " ", recommendation).strip()
|
| 182 |
explanation = re.sub(r"\s+", " ", explanation).strip()
|
|
|
|
|
|
|
| 183 |
|
| 184 |
output = []
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
if
|
| 188 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
|
| 190 |
if not output:
|
| 191 |
return "I was unable to generate a clear agricultural recommendation. Please try rephrasing your question."
|
|
@@ -266,13 +298,13 @@ def generate_response(message, history):
|
|
| 266 |
partial_text = ""
|
| 267 |
for new_text in streamer:
|
| 268 |
partial_text += new_text
|
| 269 |
-
cleaned = clean_agri_output(partial_text)
|
| 270 |
if cleaned:
|
| 271 |
history[-1]["content"] = cleaned
|
| 272 |
yield history
|
| 273 |
|
| 274 |
thread.join()
|
| 275 |
-
final_response = clean_agri_output(partial_text)
|
| 276 |
if final_response:
|
| 277 |
history[-1]["content"] = final_response
|
| 278 |
else:
|
|
|
|
| 137 |
unique_sentences.append(sentence)
|
| 138 |
return " ".join(unique_sentences)
|
| 139 |
|
| 140 |
+
def clean_agri_output(raw_text: str, user_message: str = "") -> str:
|
| 141 |
+
"""
|
| 142 |
+
Cleans model output.
|
| 143 |
+
- For Pest/Disease queries: Displays Problem, Possible Cause, Recommended Action, and Explanation.
|
| 144 |
+
- For other queries: Displays Recommended Action and Explanation.
|
| 145 |
+
"""
|
| 146 |
if not raw_text:
|
| 147 |
return ""
|
| 148 |
|
| 149 |
text = raw_text.strip()
|
| 150 |
|
| 151 |
+
# 1. Strip raw metadata key=value pairs and structural tags
|
| 152 |
text = re.sub(
|
| 153 |
+
r'(?:Context\s*:?\s*)?(?:Region|Owner|Farm|Season|Soil|Severity|Source)\s*=\s*.*?(?=\.|\n|\Z)',
|
| 154 |
'', text, flags=re.IGNORECASE
|
| 155 |
)
|
| 156 |
text = re.sub(r'\bContext\s*:?\s*', '', text, flags=re.IGNORECASE)
|
| 157 |
text = re.sub(r'https?://\S+|\[.*?\]\(.*?\)', '', text)
|
| 158 |
text = re.sub(r"<\|.*?\|>", "", text)
|
| 159 |
|
| 160 |
+
# 2. Check if the query is related to Pests or Diseases
|
| 161 |
+
pest_disease_keywords = [
|
| 162 |
+
"pest", "pests", "insect", "insects", "aphid", "thrips", "whitefly",
|
| 163 |
+
"caterpillar", "weevil", "beetle", "borer", "worm", "disease",
|
| 164 |
+
"diseases", "fungus", "fungal", "bacteria", "bacterial", "virus",
|
| 165 |
+
"viral", "blight", "rust", "mildew", "rot", "leaf spot", "spots"
|
| 166 |
+
]
|
| 167 |
+
|
| 168 |
+
combined_check_text = (user_message + " " + text).lower()
|
| 169 |
+
is_pest_or_disease = any(k in combined_check_text for k in pest_disease_keywords)
|
| 170 |
+
|
| 171 |
+
# 3. Extract sections using Regex
|
| 172 |
+
problem_match = re.search(
|
| 173 |
+
r"Problem\s*:\s*(.*?)(?=\n\s*(?:Possible Cause|Recommended Action|Recommendation|Explanation)\s*:|\Z)",
|
| 174 |
+
text, flags=re.IGNORECASE | re.DOTALL
|
| 175 |
+
)
|
| 176 |
+
cause_match = re.search(
|
| 177 |
+
r"Possible Cause\s*:\s*(.*?)(?=\n\s*(?:Problem|Recommended Action|Recommendation|Explanation)\s*:|\Z)",
|
| 178 |
+
text, flags=re.IGNORECASE | re.DOTALL
|
| 179 |
+
)
|
| 180 |
recommendation_match = re.search(
|
| 181 |
+
r"(?:Recommended Action|Recommendation)\s*:\s*(.*?)(?=\n\s*(?:Problem|Possible Cause|Explanation)\s*:|\Z)",
|
| 182 |
+
text, flags=re.IGNORECASE | re.DOTALL
|
|
|
|
| 183 |
)
|
|
|
|
|
|
|
| 184 |
explanation_match = re.search(
|
| 185 |
r"Explanation\s*:\s*(.*?)(?=\n\s*(?:Problem|Possible Cause|Recommended Action|Recommendation)\s*:|\Z)",
|
| 186 |
+
text, flags=re.IGNORECASE | re.DOTALL
|
|
|
|
| 187 |
)
|
|
|
|
| 188 |
|
| 189 |
+
problem = remove_repeated_sentences(problem_match.group(1).strip()) if problem_match else ""
|
| 190 |
+
cause = remove_repeated_sentences(cause_match.group(1).strip()) if cause_match else ""
|
| 191 |
+
recommendation = remove_repeated_sentences(recommendation_match.group(1).strip()) if recommendation_match else ""
|
| 192 |
+
explanation = remove_repeated_sentences(explanation_match.group(1).strip()) if explanation_match else ""
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
|
| 194 |
+
# Fallback cleanup for unstructured generation
|
| 195 |
+
if not recommendation:
|
| 196 |
+
cleaned = re.sub(r"^(#+\s*)?(Response|Instruction|Recommendation)\s*:\s*", "", text, flags=re.IGNORECASE)
|
| 197 |
+
recommendation = remove_repeated_sentences(re.split(r"\n#+\s*|\nContext:|\nExplanation:|\bRegion=", cleaned)[0].strip())
|
| 198 |
|
| 199 |
recommendation = re.sub(r"\s+", " ", recommendation).strip()
|
| 200 |
explanation = re.sub(r"\s+", " ", explanation).strip()
|
| 201 |
+
problem = re.sub(r"\s+", " ", problem).strip()
|
| 202 |
+
cause = re.sub(r"\s+", " ", cause).strip()
|
| 203 |
|
| 204 |
output = []
|
| 205 |
+
|
| 206 |
+
# 4. Construct response according to query type
|
| 207 |
+
if is_pest_or_disease:
|
| 208 |
+
if problem and problem != ".":
|
| 209 |
+
output.append(f"### β οΈ Problem\n\n{problem}")
|
| 210 |
+
if cause and cause != ".":
|
| 211 |
+
output.append(f"### π Possible Cause\n\n{cause}")
|
| 212 |
+
if recommendation and recommendation != ".":
|
| 213 |
+
output.append(f"### π± Recommended Action\n\n{recommendation}")
|
| 214 |
+
if explanation and explanation != ".":
|
| 215 |
+
output.append(f"### π‘ Explanation\n\n{explanation}")
|
| 216 |
+
else:
|
| 217 |
+
if recommendation and recommendation != ".":
|
| 218 |
+
output.append(f"### π± Recommended Action\n\n{recommendation}")
|
| 219 |
+
if explanation and explanation != ".":
|
| 220 |
+
output.append(f"### π‘ Explanation\n\n{explanation}")
|
| 221 |
|
| 222 |
if not output:
|
| 223 |
return "I was unable to generate a clear agricultural recommendation. Please try rephrasing your question."
|
|
|
|
| 298 |
partial_text = ""
|
| 299 |
for new_text in streamer:
|
| 300 |
partial_text += new_text
|
| 301 |
+
cleaned = clean_agri_output(partial_text, user_message=user_message)
|
| 302 |
if cleaned:
|
| 303 |
history[-1]["content"] = cleaned
|
| 304 |
yield history
|
| 305 |
|
| 306 |
thread.join()
|
| 307 |
+
final_response = clean_agri_output(partial_text, user_message=user_message)
|
| 308 |
if final_response:
|
| 309 |
history[-1]["content"] = final_response
|
| 310 |
else:
|