Spaces:
Building
Building
File size: 5,841 Bytes
d8516ac 525e493 d8516ac e17c344 525e493 b69c342 d8516ac 525e493 271d047 525e493 a074611 d8516ac 525e493 d8516ac 525e493 5b08759 0cdaf3a 4b72ada 0cdaf3a d8516ac 525e493 e17c344 d8516ac 525e493 d8516ac 5b08759 b69c342 d8516ac b69c342 d8516ac 525e493 d8516ac 525e493 a074611 525e493 a074611 d8516ac a074611 d8516ac b69c342 d8516ac 525e493 d8516ac 525e493 d8516ac 525e493 0cdaf3a 525e493 9b44949 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
"""
Flare – Session Management
~~~~~~~~~~~~~~~~~~~~~~~~~~
• thread-safe SessionStore
• state-machine alanları
"""
from __future__ import annotations
import threading, uuid, time
from datetime import datetime, timedelta
from typing import Dict, List
from utils import log
class Session:
"""Single chat session."""
def __init__(self, project_name: str, version_config=None):
self.session_id: str = str(uuid.uuid4())
self.project_name: str = project_name
self.version_number: int = version_config.id if version_config else None
self.version_config = version_config # Version config'i sakla
# 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]] = []
# smart parameter collection tracking
self.asked_parameters: Dict[str, int] = {} # parametre_adı -> kaç_kez_soruldu
self.unanswered_parameters: List[str] = [] # sorulduğu halde cevaplanmayan parametreler
self.parameter_ask_rounds: int = 0 # toplam kaç tur soru soruldu
self.created_at: datetime = datetime.now()
self.last_activity: datetime = datetime.now()
def get_version_config(self):
"""Get stored version config"""
return self.version_config
def update_activity(self):
"""Update last activity timestamp"""
self.last_activity = datetime.now()
# -------- helper ----------
def add_turn(self, role: str, content: str):
self.chat_history.append({"role": role, "content": content})
self.update_activity() # Activity güncellemesi eklendi
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
# Smart collection tracking'i reset etme,
# çünkü aynı session'da başka intent için kullanılabilir
# -------- smart parameter collection methods ------
def record_parameter_question(self, param_names: List[str]):
"""Sorulan parametreleri kaydet"""
self.parameter_ask_rounds += 1
log(f"📝 Recording parameter question round {self.parameter_ask_rounds} for: {param_names}")
for param in param_names:
self.asked_parameters[param] = self.asked_parameters.get(param, 0) + 1
log(f" - {param} asked {self.asked_parameters[param]} time(s)")
def mark_parameters_unanswered(self, param_names: List[str]):
"""Cevaplanmayan parametreleri işaretle"""
for param in param_names:
if param not in self.unanswered_parameters:
self.unanswered_parameters.append(param)
log(f"❓ Parameter marked as unanswered: {param}")
def mark_parameter_answered(self, param_name: str):
"""Parametre cevaplandığında işareti kaldır"""
if param_name in self.unanswered_parameters:
self.unanswered_parameters.remove(param_name)
log(f"✅ Parameter marked as answered: {param_name}")
def get_parameter_ask_count(self, param_name: str) -> int:
"""Bir parametrenin kaç kez sorulduğunu döndür"""
return self.asked_parameters.get(param_name, 0)
def reset_parameter_tracking(self):
"""Parametre takibini sıfırla (yeni intent için)"""
self.asked_parameters.clear()
self.unanswered_parameters.clear()
self.parameter_ask_rounds = 0
log("🔄 Parameter tracking reset for new intent")
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, version_config=None) -> Session:
with self._lock:
s = Session(project_name, version_config)
self._sessions[s.session_id] = s
log(f"🆕 Session created {s.session_id} with project {project_name} version {s.version_number}")
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
def cleanup_expired_sessions(self, timeout_minutes: int = 30):
"""Remove expired sessions"""
with self._lock:
now = datetime.now()
expired = []
for sid, session in self._sessions.items():
if (now - session.last_activity).total_seconds() > timeout_minutes * 60:
expired.append(sid)
for sid in expired:
del self._sessions[sid]
log(f"🗑️ Expired session removed: {sid[:8]}...")
if expired:
log(f"📊 Active sessions: {len(self._sessions)}")
session_store = SessionStore()
# Cleanup thread başlat
def start_session_cleanup():
def cleanup_loop():
while True:
try:
session_store.cleanup_expired_sessions()
except Exception as e:
log(f"❌ Session cleanup error: {e}")
time.sleep(300) # 5 dakikada bir
thread = threading.Thread(target=cleanup_loop, daemon=True)
thread.start()
log("🧹 Session cleanup thread started")
|