""" Flare – Session Management ~~~~~~~~~~~~~~~~~~~~~~~~~~ • thread-safe SessionStore • state-machine alanları """ from __future__ import annotations import threading, uuid from typing import Dict, List from utils import log class Session: """Single chat session.""" def __init__(self, project_name: str): self.session_id: str = str(uuid.uuid4()) self.project_name: str = project_name # flow state self.state: str = "idle" # idle | await_param | call_api | humanize self.last_intent: str | None = None self.awaiting_parameters: List[str] = [] self.missing_ask_count: int = 0 # data self.variables: Dict[str, str] = {} self.auth_tokens: Dict[str, Dict] = {} # api_name -> {token, expiry} # history self.chat_history: List[Dict[str, str]] = [] # -------- helper ---------- def add_turn(self, role: str, content: str): self.chat_history.append({"role": role, "content": content}) if len(self.chat_history) > 20: self.chat_history.pop(0) # -------- reset flow ------ def reset_flow(self): self.state = "idle" self.last_intent = None self.awaiting_parameters.clear() self.missing_ask_count = 0 class SessionStore: """Thread-safe global store.""" def __init__(self): self._lock = threading.Lock() self._sessions: Dict[str, Session] = {} def create_session(self, project_name: str) -> Session: with self._lock: s = Session(project_name) self._sessions[s.session_id] = s log(f"🆕 Session created {s.session_id}") return s def get_session(self, sid: str) -> Session | None: with self._lock: return self._sessions.get(sid) def __contains__(self, sid: str) -> bool: return self.get_session(sid) is not None session_store = SessionStore()