Buckets:
| """ | |
| Per-patient session memory for OncoAgent. | |
| Design inspired by Hermes Agent's persistent memory: | |
| - Each patient gets an isolated profile with their own clinical history. | |
| - Memory is scoped per ``patient_id``, never global. | |
| - Thread-safe via a simple dict-based store (swap for Redis/SQLite | |
| in production if needed). | |
| Usage: | |
| store = PatientMemoryStore() | |
| store.save_interaction(patient_id="P001", interaction={...}) | |
| history = store.get_history(patient_id="P001") | |
| """ | |
| import logging | |
| import uuid | |
| from datetime import datetime, timezone | |
| from typing import Dict, Any, List, Optional | |
| from dataclasses import dataclass, field | |
| logger = logging.getLogger(__name__) | |
| class PatientProfile: | |
| """Isolated memory profile for a single patient. | |
| Attributes: | |
| patient_id: Unique identifier for the patient. | |
| created_at: ISO timestamp of profile creation. | |
| interactions: Ordered list of past query/response pairs. | |
| metadata: Arbitrary metadata (e.g., preferred language). | |
| """ | |
| patient_id: str | |
| created_at: str = field( | |
| default_factory=lambda: datetime.now(timezone.utc).isoformat() | |
| ) | |
| interactions: List[Dict[str, Any]] = field(default_factory=list) | |
| metadata: Dict[str, Any] = field(default_factory=dict) | |
| def add_interaction(self, interaction: Dict[str, Any]) -> None: | |
| """Append an interaction to the patient's history. | |
| Args: | |
| interaction: Dict with at minimum ``query`` and ``response`` keys. | |
| """ | |
| interaction["timestamp"] = datetime.now(timezone.utc).isoformat() | |
| interaction["interaction_id"] = str(uuid.uuid4())[:8] | |
| self.interactions.append(interaction) | |
| logger.debug( | |
| "Patient %s: stored interaction #%d", | |
| self.patient_id, | |
| len(self.interactions), | |
| ) | |
| def get_recent_context(self, n: int = 3) -> List[Dict[str, Any]]: | |
| """Return the last *n* interactions for context injection. | |
| Args: | |
| n: Number of recent interactions to return. | |
| Returns: | |
| List of the most recent interactions (newest last). | |
| """ | |
| return self.interactions[-n:] | |
| def summary(self) -> str: | |
| """Return a brief summary string for logging/UI display.""" | |
| return ( | |
| f"Patient {self.patient_id} | " | |
| f"{len(self.interactions)} interactions | " | |
| f"Created: {self.created_at}" | |
| ) | |
| class PatientMemoryStore: | |
| """In-memory store for per-patient profiles. | |
| For hackathon scope this uses a simple dict. In production, | |
| replace with SQLite / Redis for persistence across restarts. | |
| """ | |
| def __init__(self) -> None: | |
| self._profiles: Dict[str, PatientProfile] = {} | |
| def get_or_create_profile( | |
| self, | |
| patient_id: Optional[str] = None, | |
| ) -> PatientProfile: | |
| """Retrieve an existing profile or create a new one. | |
| Args: | |
| patient_id: Existing patient ID. If None, generates a new one. | |
| Returns: | |
| The corresponding PatientProfile. | |
| """ | |
| if patient_id is None: | |
| patient_id = f"P-{str(uuid.uuid4())[:8].upper()}" | |
| if patient_id not in self._profiles: | |
| self._profiles[patient_id] = PatientProfile(patient_id=patient_id) | |
| logger.info("Created new patient profile: %s", patient_id) | |
| return self._profiles[patient_id] | |
| def save_interaction( | |
| self, | |
| patient_id: str, | |
| interaction: Dict[str, Any], | |
| ) -> None: | |
| """Save an interaction to a patient's profile. | |
| Args: | |
| patient_id: Target patient ID. | |
| interaction: Dict with query/response data. | |
| """ | |
| profile = self.get_or_create_profile(patient_id) | |
| profile.add_interaction(interaction) | |
| def get_history( | |
| self, | |
| patient_id: str, | |
| n: Optional[int] = None, | |
| ) -> List[Dict[str, Any]]: | |
| """Retrieve a patient's interaction history. | |
| Args: | |
| patient_id: Target patient ID. | |
| n: If provided, return only the last *n* interactions. | |
| Returns: | |
| List of interaction dicts. | |
| """ | |
| profile = self._profiles.get(patient_id) | |
| if profile is None: | |
| return [] | |
| if n is not None: | |
| return profile.get_recent_context(n) | |
| return profile.interactions | |
| def list_patients(self) -> List[str]: | |
| """Return all known patient IDs.""" | |
| return list(self._profiles.keys()) | |
| def patient_count(self) -> int: | |
| """Return the number of tracked patients.""" | |
| return len(self._profiles) | |
| # Module-level singleton | |
| _global_memory_store: Optional[PatientMemoryStore] = None | |
| def get_memory_store() -> PatientMemoryStore: | |
| """Return the global PatientMemoryStore singleton.""" | |
| global _global_memory_store | |
| if _global_memory_store is None: | |
| _global_memory_store = PatientMemoryStore() | |
| return _global_memory_store | |
Xet Storage Details
- Size:
- 5.02 kB
- Xet hash:
- 39abf987fae7640730f6e45c134baf941ef9bf7e0a59ff8d16a0b05b38552a29
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.