dmChatbotBackend / src /tools /patient_memory.py
github-actions
Auto deploy from GitHub
76962bf
Raw
History Blame Contribute Delete
3.8 kB
import os
import uuid
import datetime
from supabase import create_client, Client
from langchain_core.tools import tool
from src.utils.logger import setup_logger
logger = setup_logger("FHIRPatientMemory")
def _get_client() -> Client:
url = os.getenv("SUPABASE_URL")
key = os.getenv("SUPABASE_KEY")
return create_client(url, key)
@tool
def save_patient_memory(patient_id: str, glucose_history: str = None, medications: str = None, diet: str = None):
"""
Save patient memory (narrative context) as strict FHIR Observation resources.
"""
logger.info(f"Saving FHIR narrative memory for patient: {patient_id}")
client = _get_client()
results = []
# Map narrative categories to FHIR-like coding
categories = {
"glucose_history": {"code": "narrative-glucose", "display": "Glucose History Narrative"},
"medications": {"code": "narrative-meds", "display": "Medications Narrative"},
"diet": {"code": "narrative-diet", "display": "Dietary Narrative"}
}
for key, value in [("glucose_history", glucose_history), ("medications", medications), ("diet", diet)]:
if value is not None:
obs_id = str(uuid.uuid4())
fhir_obs = {
"resourceType": "Observation",
"id": obs_id,
"status": "final",
"code": {
"coding": [{
"system": "http://dm-chatbot.ai/codes",
"code": categories[key]["code"],
"display": categories[key]["display"]
}]
},
"subject": {"reference": f"Patient/{patient_id}"},
"effectiveDateTime": datetime.datetime.now(datetime.timezone.utc).isoformat(),
"valueString": value # Using valueString for narrative text
}
data = {
"id": obs_id,
"patient_id": patient_id,
"resource": fhir_obs,
"last_updated": datetime.datetime.now(datetime.timezone.utc).isoformat()
}
client.table("observations").insert(data).execute()
results.append(key)
return f"Successfully saved FHIR narrative memory for: {', '.join(results)}"
@tool
def get_patient_memory(patient_id: str):
"""
Retrieve patient narrative memory from FHIR Observation resources.
"""
logger.info(f"Retrieving FHIR narrative memory for patient: {patient_id}")
client = _get_client()
try:
# Fetch observations with narrative codes
response = client.table("observations").select("resource").eq("patient_id", patient_id).execute()
observations = [r["resource"] for r in response.data]
# Filter for narrative codes
memory = {}
codes_map = {
"narrative-glucose": "Glucose History",
"narrative-meds": "Medications",
"narrative-diet": "Diet"
}
for obs in observations:
for coding in obs.get("code", {}).get("coding", []):
code = coding.get("code")
if code in codes_map:
# Keep only the latest one for each category
memory[codes_map[code]] = obs.get("valueString", "N/A")
if not memory:
return f"No FHIR narrative memory found for patient {patient_id}."
output = f"Patient Narrative Memory (FHIR) for {patient_id}:\n"
for cat, val in memory.items():
output += f"- {cat}: {val}\n"
return output
except Exception as e:
logger.error(f"Error retrieving FHIR memory: {e}")
return f"Error retrieving FHIR memory: {str(e)}"