Aniket2006 commited on
Commit
a8d7d80
·
1 Parent(s): cb3e125

Enhanced compact context: ALL 13 indices, clusters, prev_analysis, conv_history

Browse files
Files changed (1) hide show
  1. prompts.py +132 -25
prompts.py CHANGED
@@ -731,7 +731,7 @@ def format_weather_context(weather_data: dict) -> str:
731
  def build_compact_context(context: Dict) -> str:
732
  """
733
  Build a compressed context string using abbreviations and key-value format.
734
- Captures all essential data in ~50% fewer tokens.
735
 
736
  Format: KEY:value pairs, one per line, grouped by category.
737
  """
@@ -742,55 +742,120 @@ def build_compact_context(context: Dict) -> str:
742
  if field:
743
  lines.append(f"[FIELD] {field.get('name','?')} | {field.get('crop_type','?')} | {field.get('area_acres',0):.1f}ac")
744
 
745
- # --- Vegetation Indices (compact key:value format) ---
746
  veg = context.get("vegetation_indices", {})
747
  if veg:
748
- veg_parts = []
 
749
  for k in ["ndvi", "evi", "ndre", "smi", "ndwi"]:
750
- if k in veg and veg[k] is not None:
751
- veg_parts.append(f"{k.upper()}:{veg[k]:.2f}")
752
- if veg_parts:
753
- lines.append(f"[VEG] " + " | ".join(veg_parts))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
754
 
755
  # --- Health Summary (single line) ---
756
  health = context.get("health_summary", {})
757
  if health:
758
  score = health.get("overall_stress", health.get("stress_score", health.get("average_stress_score", 0)))
759
  status = health.get("status", health.get("crop_health", "unknown"))
760
- lines.append(f"[HEALTH] score:{score:.2f} status:{status}")
 
 
 
 
761
 
762
- # --- Stressed Patches (count + top 2) ---
763
  patches = context.get("stressed_patches", [])
764
  if patches:
765
  lines.append(f"[STRESS] {len(patches)} patches")
766
- for p in patches[:2]:
767
- lines.append(f" - zone:{p.get('patch_id','?')} stress:{p.get('stress_score',0):.2f}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
768
 
769
  # --- SAR Bands (compact) ---
770
  sar = context.get("sar_bands", {})
771
  if sar:
772
  sar_parts = []
773
- if "vv" in sar: sar_parts.append(f"VV:{sar['vv']:.2f}")
774
- if "vh" in sar: sar_parts.append(f"VH:{sar['vh']:.2f}")
775
- if "ratio" in sar: sar_parts.append(f"ratio:{sar['ratio']:.2f}")
 
 
 
 
 
776
  if sar_parts:
777
- lines.append(f"[SAR] " + " | ".join(sar_parts))
778
 
779
- # --- Weather (compressed) ---
780
  weather = context.get("weather", {})
781
  if weather:
782
  current = weather.get("current", {})
783
  if current:
784
  lines.append(f"[WX] T:{current.get('temp',0):.0f}°C H:{current.get('humidity',0):.0f}% Rain:{current.get('precip',0):.0f}mm")
 
 
 
 
 
 
 
 
 
785
  stress = weather.get("stress_indicators", {})
786
  flags = []
787
  if stress.get("current_heat_stress"): flags.append("HEAT")
 
788
  if stress.get("drought_risk"): flags.append("DROUGHT")
789
  if stress.get("suitable_for_irrigation"): flags.append("OK_IRRIG")
 
790
  if flags:
791
  lines.append(f"[WX_ALERT] " + ",".join(flags))
792
 
793
- # --- Soil (compact) ---
794
  soil = context.get("soil_indicators", {})
795
  if soil:
796
  soil_parts = []
@@ -801,20 +866,62 @@ def build_compact_context(context: Dict) -> str:
801
  if soil_parts:
802
  lines.append(f"[SOIL] " + " | ".join(soil_parts))
803
 
804
- # --- Trends (single line) ---
805
  trends = context.get("historical_trends", {})
806
- if trends and trends.get("summary"):
807
- lines.append(f"[TREND] {trends['summary'][:80]}")
808
-
809
- # --- Zone Analysis (compact) ---
 
 
 
 
 
 
 
 
 
 
 
810
  zones = context.get("zone_analysis", {})
811
- if zones and zones.get("most_critical"):
812
- mc = zones["most_critical"]
813
- lines.append(f"[ZONE_ALERT] {mc.get('location','?')} stress:{mc.get('stress_score',0):.2f}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
814
 
815
  return "\n".join(lines) if lines else "No data"
816
 
817
 
 
818
  # =============================================================================
819
  # COMPRESSED STAGE PROMPTS - Reduce Token Usage
820
  # =============================================================================
 
731
  def build_compact_context(context: Dict) -> str:
732
  """
733
  Build a compressed context string using abbreviations and key-value format.
734
+ Captures ALL essential data in ~50% fewer tokens.
735
 
736
  Format: KEY:value pairs, one per line, grouped by category.
737
  """
 
742
  if field:
743
  lines.append(f"[FIELD] {field.get('name','?')} | {field.get('crop_type','?')} | {field.get('area_acres',0):.1f}ac")
744
 
745
+ # --- ALL Vegetation Indices (compact key:value format) ---
746
  veg = context.get("vegetation_indices", {})
747
  if veg:
748
+ # Primary indices (most important)
749
+ primary = []
750
  for k in ["ndvi", "evi", "ndre", "smi", "ndwi"]:
751
+ val = veg.get(k) or veg.get(k.upper())
752
+ if val is not None:
753
+ try:
754
+ primary.append(f"{k.upper()}:{float(val):.2f}")
755
+ except (ValueError, TypeError):
756
+ pass
757
+ if primary:
758
+ lines.append(f"[VEG1] " + " | ".join(primary))
759
+
760
+ # Secondary indices (stress/health indicators)
761
+ secondary = []
762
+ for k in ["psri", "pri", "mcari", "osavi", "reci"]:
763
+ val = veg.get(k) or veg.get(k.upper())
764
+ if val is not None:
765
+ try:
766
+ secondary.append(f"{k.upper()}:{float(val):.2f}")
767
+ except (ValueError, TypeError):
768
+ pass
769
+ if secondary:
770
+ lines.append(f"[VEG2] " + " | ".join(secondary))
771
+
772
+ # Soil indices
773
+ soil_idx = []
774
+ for k in ["sasi", "somi", "sfi"]:
775
+ val = veg.get(k) or veg.get(k.upper())
776
+ if val is not None:
777
+ try:
778
+ soil_idx.append(f"{k.upper()}:{float(val):.2f}")
779
+ except (ValueError, TypeError):
780
+ pass
781
+ if soil_idx:
782
+ lines.append(f"[SOIL_IDX] " + " | ".join(soil_idx))
783
 
784
  # --- Health Summary (single line) ---
785
  health = context.get("health_summary", {})
786
  if health:
787
  score = health.get("overall_stress", health.get("stress_score", health.get("average_stress_score", 0)))
788
  status = health.get("status", health.get("crop_health", "unknown"))
789
+ conf = health.get("confidence_score", health.get("confidence", 0))
790
+ try:
791
+ lines.append(f"[HEALTH] score:{float(score):.2f} status:{status} conf:{float(conf):.2f}")
792
+ except (ValueError, TypeError):
793
+ lines.append(f"[HEALTH] status:{status}")
794
 
795
+ # --- Stressed Patches (count + top 5) ---
796
  patches = context.get("stressed_patches", [])
797
  if patches:
798
  lines.append(f"[STRESS] {len(patches)} patches")
799
+ for p in patches[:5]: # Top 5 patches
800
+ pid = p.get('patch_id', p.get('id', '?'))
801
+ score = p.get('stress_score', p.get('score', 0))
802
+ try:
803
+ lines.append(f" P{pid}:{float(score):.2f}")
804
+ except (ValueError, TypeError):
805
+ lines.append(f" P{pid}")
806
+
807
+ # --- Clustering Data (critical for zone analysis) ---
808
+ stress_analysis = context.get("stress_analysis", {})
809
+ clusters = stress_analysis.get("cluster_statistics", [])
810
+ if clusters:
811
+ lines.append(f"[CLUSTERS] {len(clusters)} zones")
812
+ for c in clusters[:3]: # Top 3 clusters
813
+ cid = c.get('cluster_id', '?')
814
+ pct = c.get('percentage', 0)
815
+ stress = c.get('stress_score', {}).get('mean', 0) if isinstance(c.get('stress_score'), dict) else 0
816
+ lines.append(f" C{cid}:{pct:.1f}% stress:{stress:.2f}")
817
 
818
  # --- SAR Bands (compact) ---
819
  sar = context.get("sar_bands", {})
820
  if sar:
821
  sar_parts = []
822
+ for k in ["vv", "vh", "ratio", "VV", "VH"]:
823
+ if k.lower() in sar or k in sar:
824
+ val = sar.get(k.lower()) or sar.get(k)
825
+ if val is not None:
826
+ try:
827
+ sar_parts.append(f"{k.upper()}:{float(val):.2f}")
828
+ except (ValueError, TypeError):
829
+ pass
830
  if sar_parts:
831
+ lines.append(f"[SAR] " + " | ".join(sar_parts[:3]))
832
 
833
+ # --- Weather (compressed with forecast) ---
834
  weather = context.get("weather", {})
835
  if weather:
836
  current = weather.get("current", {})
837
  if current:
838
  lines.append(f"[WX] T:{current.get('temp',0):.0f}°C H:{current.get('humidity',0):.0f}% Rain:{current.get('precip',0):.0f}mm")
839
+
840
+ # Add 3-day forecast summary
841
+ forecast = weather.get("forecast_7d", weather.get("forecast", []))
842
+ if forecast and len(forecast) > 0:
843
+ rain_days = sum(1 for d in forecast[:3] if d.get('precipitation', 0) > 5)
844
+ max_temp = max((d.get('temp_max', 0) for d in forecast[:3]), default=0)
845
+ lines.append(f"[FORECAST] 3d_rain_days:{rain_days} max_T:{max_temp:.0f}°C")
846
+
847
+ # Weather alerts
848
  stress = weather.get("stress_indicators", {})
849
  flags = []
850
  if stress.get("current_heat_stress"): flags.append("HEAT")
851
+ if stress.get("predicted_heat_stress"): flags.append("HEAT_RISK")
852
  if stress.get("drought_risk"): flags.append("DROUGHT")
853
  if stress.get("suitable_for_irrigation"): flags.append("OK_IRRIG")
854
+ if stress.get("suitable_for_spraying"): flags.append("OK_SPRAY")
855
  if flags:
856
  lines.append(f"[WX_ALERT] " + ",".join(flags))
857
 
858
+ # --- Soil Indicators (compact) ---
859
  soil = context.get("soil_indicators", {})
860
  if soil:
861
  soil_parts = []
 
866
  if soil_parts:
867
  lines.append(f"[SOIL] " + " | ".join(soil_parts))
868
 
869
+ # --- Historical Trends (more detail) ---
870
  trends = context.get("historical_trends", {})
871
+ if trends:
872
+ summary = trends.get("summary", "")
873
+ if summary:
874
+ lines.append(f"[TREND] {summary[:120]}")
875
+ # Add specific trend data
876
+ ndvi_trend = trends.get("ndvi_change") or trends.get("NDVI_change")
877
+ smi_trend = trends.get("smi_change") or trends.get("SMI_change")
878
+ if ndvi_trend or smi_trend:
879
+ parts = []
880
+ if ndvi_trend: parts.append(f"NDVI:{ndvi_trend:+.2f}")
881
+ if smi_trend: parts.append(f"SMI:{smi_trend:+.2f}")
882
+ if parts:
883
+ lines.append(f"[TREND_DATA] " + " ".join(parts))
884
+
885
+ # --- Zone Analysis (all critical zones) ---
886
  zones = context.get("zone_analysis", {})
887
+ if zones:
888
+ priority_zones = zones.get("priority_zones", [])
889
+ if priority_zones:
890
+ lines.append(f"[ZONES] {len(priority_zones)} priority areas")
891
+ for z in priority_zones[:3]:
892
+ loc = z.get('location', '?')
893
+ score = z.get('stress_score', 0)
894
+ lines.append(f" {loc}: stress:{score:.2f}")
895
+ elif zones.get("most_critical"):
896
+ mc = zones["most_critical"]
897
+ lines.append(f"[ZONE_ALERT] {mc.get('location','?')} stress:{mc.get('stress_score',0):.2f}")
898
+
899
+ # --- Previous Analysis (LLM insights from satellite) ---
900
+ prev = context.get("previous_analysis", {})
901
+ if prev:
902
+ rec = prev.get("recommendation", prev.get("recommendations", ""))
903
+ if rec:
904
+ rec_text = rec[0] if isinstance(rec, list) else str(rec)
905
+ lines.append(f"[PREV_REC] {rec_text[:80]}")
906
+
907
+ concerns = prev.get("key_concerns", [])
908
+ if concerns and isinstance(concerns, list):
909
+ lines.append(f"[CONCERNS] " + ", ".join(str(c)[:30] for c in concerns[:3]))
910
+
911
+ # --- Conversation History (for follow-ups) ---
912
+ conv = context.get("conversation_history", [])
913
+ if conv:
914
+ lines.append(f"[CONV] {len(conv)} prior turns")
915
+ if len(conv) > 0:
916
+ last = conv[-1]
917
+ role = last.get("role", "")
918
+ content = last.get("content", "")[:50]
919
+ lines.append(f" Last: {role}: {content}...")
920
 
921
  return "\n".join(lines) if lines else "No data"
922
 
923
 
924
+
925
  # =============================================================================
926
  # COMPRESSED STAGE PROMPTS - Reduce Token Usage
927
  # =============================================================================