File size: 3,389 Bytes
d8516ac
 
 
 
 
525e493
 
d8516ac
e17c344
 
525e493
b69c342
 
 
d8516ac
525e493
 
 
 
d8516ac
 
 
525e493
 
d8516ac
 
 
 
 
 
 
525e493
 
0cdaf3a
 
 
 
 
 
 
d8516ac
 
525e493
e17c344
d8516ac
525e493
 
d8516ac
 
 
 
 
 
b69c342
 
 
d8516ac
b69c342
d8516ac
525e493
d8516ac
525e493
 
 
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
"""
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):
        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]] = []

        self.created_at: datetime = datetime.now()
        self.last_activity: datetime = datetime.now()

    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


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

    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")