push final changes
Browse files- app/agents/climate_agent.py +5 -0
- app/main.py +8 -1
- app/utils/text_cleaning.py +7 -9
app/agents/climate_agent.py
CHANGED
|
@@ -208,6 +208,11 @@ def advise_climate_resilient(
|
|
| 208 |
a photo is provided and GEMINI_API_KEY is configured. Falls back to
|
| 209 |
text-only Qwen when Gemini is unavailable or the image is invalid.
|
| 210 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 211 |
gemini_client = load_gemini_client()
|
| 212 |
use_multimodal = gemini_client is not None and image_bytes is not None
|
| 213 |
|
|
|
|
| 208 |
a photo is provided and GEMINI_API_KEY is configured. Falls back to
|
| 209 |
text-only Qwen when Gemini is unavailable or the image is invalid.
|
| 210 |
"""
|
| 211 |
+
if crop and crop.strip().lower() in ("string", "none", "null", ""):
|
| 212 |
+
crop = None
|
| 213 |
+
if growth_stage and growth_stage.strip().lower() in ("string", "none", "null", ""):
|
| 214 |
+
growth_stage = None
|
| 215 |
+
|
| 216 |
gemini_client = load_gemini_client()
|
| 217 |
use_multimodal = gemini_client is not None and image_bytes is not None
|
| 218 |
|
app/main.py
CHANGED
|
@@ -487,9 +487,16 @@ async def advise_climate_resilient_endpoint(
|
|
| 487 |
|
| 488 |
Rate limited: 10 requests per minute per IP (higher compute cost).
|
| 489 |
"""
|
| 490 |
-
if
|
|
|
|
|
|
|
| 491 |
session_id = str(uuid.uuid4())
|
| 492 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 493 |
logging.info(f"Advise request: {query[:50]}... [session_id={session_id}]")
|
| 494 |
|
| 495 |
image_bytes = await photo.read() if photo is not None else None
|
|
|
|
| 487 |
|
| 488 |
Rate limited: 10 requests per minute per IP (higher compute cost).
|
| 489 |
"""
|
| 490 |
+
if session_id and session_id.strip().lower() in ("string", "none", "null", ""):
|
| 491 |
+
session_id = str(uuid.uuid4())
|
| 492 |
+
elif not session_id:
|
| 493 |
session_id = str(uuid.uuid4())
|
| 494 |
|
| 495 |
+
if crop and crop.strip().lower() in ("string", "none", "null", ""):
|
| 496 |
+
crop = None
|
| 497 |
+
if growth_stage and growth_stage.strip().lower() in ("string", "none", "null", ""):
|
| 498 |
+
growth_stage = None
|
| 499 |
+
|
| 500 |
logging.info(f"Advise request: {query[:50]}... [session_id={session_id}]")
|
| 501 |
|
| 502 |
image_bytes = await photo.read() if photo is not None else None
|
app/utils/text_cleaning.py
CHANGED
|
@@ -119,7 +119,8 @@ def cap_summary(
|
|
| 119 |
) -> List[str]:
|
| 120 |
"""
|
| 121 |
Return the first `max_sentences` sentences, truncated so the joined
|
| 122 |
-
output does not exceed `max_chars` characters.
|
|
|
|
| 123 |
"""
|
| 124 |
if not sentences:
|
| 125 |
return []
|
|
@@ -130,14 +131,11 @@ def cap_summary(
|
|
| 130 |
# +1 accounts for the joining space between sentences.
|
| 131 |
prospective = total + len(sentence) + (1 if kept else 0)
|
| 132 |
if prospective > max_chars:
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
break
|
| 139 |
-
kept.append(sentence)
|
| 140 |
-
total += len(sentence) + (1 if len(kept) > 1 else 0)
|
| 141 |
break
|
| 142 |
kept.append(sentence)
|
| 143 |
total = prospective
|
|
|
|
| 119 |
) -> List[str]:
|
| 120 |
"""
|
| 121 |
Return the first `max_sentences` sentences, truncated so the joined
|
| 122 |
+
output does not exceed `max_chars` characters. Preserves complete sentences
|
| 123 |
+
whenever possible without cutting off in the middle of words.
|
| 124 |
"""
|
| 125 |
if not sentences:
|
| 126 |
return []
|
|
|
|
| 131 |
# +1 accounts for the joining space between sentences.
|
| 132 |
prospective = total + len(sentence) + (1 if kept else 0)
|
| 133 |
if prospective > max_chars:
|
| 134 |
+
if not kept:
|
| 135 |
+
# If even the very first sentence exceeds max_chars, truncate cleanly.
|
| 136 |
+
sentence = sentence[:max_chars].rstrip()
|
| 137 |
+
if sentence:
|
| 138 |
+
kept.append(sentence)
|
|
|
|
|
|
|
|
|
|
| 139 |
break
|
| 140 |
kept.append(sentence)
|
| 141 |
total = prospective
|