import os import json import re DATA_DIR = os.path.dirname(os.path.abspath(__file__)) + "/data" GUIDES_FILE = DATA_DIR + "/agri_guides.json" def retrieve_guides(query_text, crop_name, lang="hi"): """ Search agri_guides.json for guides relevant to the query and crop. Returns (markdown_grounding_text, source_list) or (None, []) """ if not os.path.exists(GUIDES_FILE): print(f"[rag.py] Guide file not found at {GUIDES_FILE}") return None, [] try: with open(GUIDES_FILE, "r", encoding="utf-8") as f: guides = json.load(f) except Exception as e: print(f"[rag.py] Error reading guides: {e}") return None, [] # Clean query text query_text_lower = query_text.lower() query_words = set(re.findall(r"\w+", query_text_lower)) matches = [] for guide in guides: # Filter by crop (case-insensitive check) if guide["crop"].lower() != crop_name.lower(): continue score = 0 # Check keyword matches for keyword in guide.get("keywords", []): if keyword.lower() in query_text_lower: score += 3 # High weight for exact keyword matching # Check general word overlap in query guide_text = (guide.get("title_en", "") + " " + guide.get("content_en", "") + " " + guide.get("title_hi", "") + " " + guide.get("content_hi", "")).lower() for word in query_words: if len(word) > 2 and word in guide_text: score += 1 if score > 0: matches.append((score, guide)) # Sort matches by score descending matches.sort(key=lambda x: x[0], reverse=True) if not matches: return None, [] # Build markdown grounding context and source citation list grounding_parts = [] sources = [] # Take top-2 matching guides for idx, (score, guide) in enumerate(matches[:2]): title = guide["title_en"] if lang in ["en", "hinglish"] else guide["title_hi"] content = guide["content_en"] if lang in ["en", "hinglish"] else guide["content_hi"] topic = guide["topic"] grounding_parts.append( f"### {title}\n" f"{content}\n" ) sources.append(f"{guide['crop']} Guide: {topic}") grounding_text = "\n---\n".join(grounding_parts) return grounding_text, sources