serinity / core /ports.py
Amogh1221's picture
Update core/ports.py
484aaf0 verified
Raw
History Blame Contribute Delete
7.39 kB
from typing import Protocol, List, Optional, Any, Dict
from pydantic import BaseModel
class LLM1Output(BaseModel):
"""
Data model representing the output of the conversational LLM (LLM1).
Used to structure the immediate response sent to the patient.
"""
assistant_message: str
intent: str
risk_flag: bool = False
clinical_summary: Optional[str] = None
search_query: Optional[str] = None
class LLM2Output(BaseModel):
"""
Data model representing the output of the analytical LLM (LLM2).
Used to structure the background psychological analysis of the patient's state.
"""
assistant_message: str
emotional_themes: List[str]
thinking_patterns: List[str]
behavioral_patterns: List[str]
interpersonal_dynamics: List[str]
stressors: List[str]
unclear_areas: List[str]
risk_assessment: str
protective_factors: List[str]
class LLM3Output(BaseModel):
"""
Data model representing the output of the post-session LLM (LLM3).
Used for summarizing the session and merging the clinical profile.
"""
session_summary: str
update_profile: bool
emotional_themes: List[str]
thinking_patterns: List[str]
behavioral_patterns: List[str]
interpersonal_dynamics: List[str]
stressors: List[str]
unclear_areas: List[str]
risk_assessment: str
protective_factors: List[str]
updated_primary_concern: Optional[str] = None
class RiskSignal(Protocol):
"""
Protocol for evaluating patient messages against specific risk criteria
(e.g. self-harm, crisis). Multiple signals can be combined in the RiskAssessmentService.
"""
def check(self, message: str, llm1_output: LLM1Output, llm2_output: Optional[LLM2Output] = None) -> bool:
"""Evaluate if there is a risk flag present in the current turn."""
...
class LLMProvider(Protocol):
"""
Protocol defining the interface for connecting to Large Language Models.
Abstracts away specific LLM implementations (e.g. Ollama, OpenAI) from the core logic.
"""
def generate_opening_context(self, profile_recap: Optional[str]) -> list:
"""Generate the system/user prompt context for starting a session."""
...
def psychiatrist_response(self, context: list, patient_info: dict = None, medium_term_memory: str | None = None) -> LLM1Output:
"""Generate a conversational response mimicking a psychiatrist (LLM1 fast path)."""
...
def internal_reasoning(self, context: list, stable_prefix: str | None = None) -> LLM2Output:
"""Perform a deep psychological analysis of the conversation history (LLM2 slow path)."""
...
def psychiatrist_query_response(self, context: list, retrieved_context: str) -> str:
"""Synthesize a final response to a user's query using retrieved clinical guidelines (LLM1 sync path)."""
...
def generate_end_of_session_profile(self, old_profile: dict, session_history: list, patient_info: dict = None) -> 'LLM3Output':
"""Generate a concise session summary and fully merged clinical profile (LLM3 post-session path)."""
...
class STTProvider(Protocol):
"""
Protocol for Speech-to-Text services.
Abstracts audio transcription logic from the API layer.
"""
def transcribe(self, audio_bytes: bytes) -> Dict[str, Any]:
"""Convert audio bytes to text and extract emotional metadata."""
...
class VectorStore(Protocol):
"""
Protocol for semantic vector databases.
Used for retrieving relevant psychological context or clinical guidelines.
"""
def retrieve(self, query: str, k: int = 8) -> str:
"""Retrieve top semantic matches as a concatenated string."""
...
class SessionStore(Protocol):
"""
Protocol for managing active conversational sessions.
Responsible for tracking the immediate history and message context.
"""
def create_session(self, patient_id: Optional[str] = None) -> str:
"""Initialize a new session and return the session ID."""
...
def session_exists(self, session_id: str) -> bool:
"""Check if a session ID is currently active."""
...
def append_message(self, session_id: str, role: str, content: str) -> None:
"""Add a new message (user or assistant) to the session history."""
...
def get_working_context(self, session_id: str, llm_engine: Any = None) -> list:
"""Retrieve the formatted message history for the current session."""
...
def save_session_summary(self, session_id: str, summary: str) -> None:
"""Persist the generated summary of the session when it ends."""
...
def end_session(self, session_id: str) -> None:
"""Explicitly mark a session as ended, updating timestamps and setting is_active to 0."""
...
def get_abandoned_sessions(self, timeout_minutes: int) -> list[str]:
"""Return a list of session IDs that have been inactive longer than timeout_minutes."""
...
def get_patient_id(self, session_id: str) -> Optional[str]:
"""Lookup the associated patient ID for a given session."""
...
def get_session_count(self, patient_id: str) -> int:
"""Get the total number of sessions for a given patient."""
...
def get_active_session(self, patient_id: str) -> Optional[str]:
...
def get_all_messages(self, session_id: str) -> list[dict]:
...
class ProfileStore(Protocol):
"""
Protocol for managing long-term patient profiles.
Responsible for storing demographic data, tracking past sessions, and updating psychological profiles.
"""
def create_patient(self, name: str, age: Optional[int] = None) -> str:
"""Create a new patient record and return their ID."""
...
def list_patients(self) -> list:
"""Return a list of all registered patients."""
...
def get_patient(self, patient_id: str) -> dict:
"""Retrieve basic demographic info for a specific patient."""
...
def get_patient_sessions(self, patient_id: str) -> list:
"""Retrieve a list of all past sessions for a patient."""
...
def delete_patient(self, patient_id: str) -> None:
"""Delete all records associated with a patient."""
...
def reset_patient_data(self, patient_id: str) -> None:
"""Delete sessions, messages, and profiles, but keep the patient record."""
...
def update_patient_profile(self, patient_id: str, llm3_output: LLM3Output) -> None:
"""Merge final post-session insights into the patient's long-term dashboard profile."""
...
def get_long_term_memory(self, patient_id: str) -> dict:
"""Retrieve the working long-term memory for the patient used by LLM1."""
...
def update_long_term_memory(self, patient_id: str, llm2_output: LLM2Output) -> None:
"""Update the working long-term memory with mid-session LLM2 insights."""
...
def get_patient_profile(self, patient_id: str) -> dict:
"""Retrieve the aggregated psychological profile of a patient."""
...
def build_profile_recap(self, patient_id: str) -> Optional[str]:
"""Generate a concise text recap of the patient's profile for LLM context."""
...