demeter
Autonomous Hydroponic Intelligencegit clone https://github.com/maydayv7/demeter
agent/sub_agents/water_and_atmospheric_dependencies/retrieval.py (3797B)
1import os
2import json
3from langchain.tools import tool
4from qdrant_client import QdrantClient
5
6# Import your existing modules
7from agent.sub_agents.Researcher import ResearcherAgent
8from agent.Qdrant.Store import COLLECTION_NAME
9
10from agent.sub_agents.Doctor import VisionAgent
11from agent.memory import FarmMemory
12
13# Initialize shared clients
14# Note: We rely on the existing ResearcherAgent logic for embeddings/search
15researcher_instance = ResearcherAgent()
16farm_memory = FarmMemory()
17
18# Initialize Qdrant for the Historian
19qdrant_client = QdrantClient(
20 url=os.environ.get("QDRANT_URL", "http://localhost:6333"),
21 api_key=os.environ.get("QDRANT_API_KEY"),
22)
23
24doctor = VisionAgent()
25
26@tool
27def diagnose_plant(image_b64: str = None):
28 """
29 Uses Computer Vision to scan the latest plant image for disease.
30
31 INSTRUCTIONS FOR LLM:
32 Call this tool with NO arguments. The system will automatically
33 attach the latest camera feed for you.
34 """
35 if not image_b64:
36 return {"error": "System Error: No visual data was injected into the tool call."}
37
38 # Calls the analyze_frame method you updated earlier
39 result = doctor.analyze_frame(image_b64)
40 print(f"Diagnose Plant Result: {result}")
41 return result
42
43@tool
44def ask_memory(plant_id: str):
45 """
46 Consult the Farm Memory for past events, strategies, and outcomes.
47 Useful for recalling what has been tried before and its results.
48
49 Args:
50 plant_id: The specific crop ID to look up (e.g. "crop_beta").
51 """
52 print(f"Consulting Farm Memory for plant ID: {plant_id}")
53 try:
54 # Fixed: calling the wrapper method directly on the instance
55 response = farm_memory.get_plant_history(plant_id)
56 print(f"Memory response for {plant_id}: {response}")
57 return response
58 except Exception as e:
59 return f"Memory unavailable: {str(e)}"
60
61@tool
62def ask_historian(query: str):
63 """
64 Search the Farm's Database (History) for similar past events.
65 Useful for checking past mistakes, success rates, or specific scenarios.
66
67 Args:
68 query: A description of the situation to look up (e.g. "What happened when pH dropped to 5.5?")
69 """
70 try:
71 # 1. Generate Embedding using Researcher's Encoder (384 dims)
72 # .embed() returns a generator, convert to list and take first item
73 embeddings = list(researcher_instance.encoder.embed([query]))
74 query_vector = embeddings[0].tolist()
75
76 # 2. Search the TEXT collection (Plant_Biographies_HF)
77 # We CANNOT search COLLECTION_NAME (Farm_Memory) because the vector dimensions don't match.
78 hits = qdrant_client.query_points(
79 collection_name="Plant_Biographies_HF ",
80 query=query_vector,
81 limit=3
82 )
83
84 results = []
85 for hit in hits:
86 # Handle different payload structures
87 content = hit.payload.get('text', hit.payload.get('memory', ''))
88 source = hit.payload.get('source', hit.payload.get('user_id', 'Unknown'))
89 results.append(f"[{source}]: {content}")
90
91 return "\n".join(results) if results else "No relevant history found."
92
93 except Exception as e:
94 return f"Historian unavailable: {str(e)}"
95
96@tool
97def ask_rag(query: str):
98 """
99 Consult the Research Assistant (RAG) for scientific knowledge.
100 Useful for finding optimal ranges, chemical interactions, or biological facts.
101
102 Args:
103 query: Scientific question (e.g. "Optimal VPD for Lettuce in late flower")
104 """
105 try:
106 # Reuse your existing ResearcherAgent logic
107 return researcher_instance.search(query)
108 except Exception as e:
109 return f"Research unavailable: {str(e)}"
110