| 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 = [] |
| |
| |
| 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 |
| } |
| |
| 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: |
| |
| response = client.table("observations").select("resource").eq("patient_id", patient_id).execute() |
| observations = [r["resource"] for r in response.data] |
| |
| |
| 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: |
| |
| 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)}" |
|
|