HumboldtJoker commited on
Commit
dbe9115
·
verified ·
1 Parent(s): 68e7196

Clean up nested duplicate: v2/v2/engine/session.py

Browse files
Files changed (1) hide show
  1. v2/v2/engine/session.py +0 -82
v2/v2/engine/session.py DELETED
@@ -1,82 +0,0 @@
1
- """Per-user sessions with evidence tracking.
2
-
3
- Confidence in Rivet is earned, not asserted. Every file a chip actually
4
- reads during a plan is recorded here; the discipline gate grades the
5
- final answer against this record:
6
-
7
- HIGH the answer's claims are backed by source files read this session
8
- MEDIUM backed by architecture map / audit / pack knowledge only
9
- LOW reasoning from architecture with no matching source at all
10
-
11
- Sessions are isolated per user (faculty-wide deployment requirement —
12
- no context bleed between users).
13
- """
14
-
15
- import time
16
- from dataclasses import dataclass, field
17
-
18
-
19
- @dataclass
20
- class Session:
21
- user_id: str
22
- created_at: float = field(default_factory=time.time)
23
- last_active: float = field(default_factory=time.time)
24
- history: list = field(default_factory=list) # [{role, content}]
25
- files_read: set = field(default_factory=set) # repo-relative paths
26
- evidence: list = field(default_factory=list) # [{kind, ref, chip}]
27
- request_count: int = 0
28
-
29
- def touch(self) -> None:
30
- self.last_active = time.time()
31
-
32
- def record_file_read(self, path: str, chip: str) -> None:
33
- self.files_read.add(path)
34
- self.evidence.append({"kind": "source_file", "ref": path, "chip": chip})
35
-
36
- def record_evidence(self, kind: str, ref: str, chip: str) -> None:
37
- self.evidence.append({"kind": kind, "ref": ref, "chip": chip})
38
-
39
- def add_turn(self, role: str, content: str, max_turns: int = 20) -> None:
40
- self.history.append({"role": role, "content": content})
41
- if len(self.history) > max_turns:
42
- self.history = self.history[-max_turns:]
43
-
44
-
45
- class SessionManager:
46
- def __init__(self, ttl_seconds: int = 3600, rate_limit_per_hour: int = 60):
47
- self.ttl = ttl_seconds
48
- self.rate_limit = rate_limit_per_hour
49
- self._sessions: dict[str, Session] = {}
50
- self._request_log: dict[str, list] = {}
51
-
52
- def get(self, user_id: str) -> Session:
53
- self._expire()
54
- session = self._sessions.get(user_id)
55
- if session is None:
56
- session = Session(user_id=user_id)
57
- self._sessions[user_id] = session
58
- session.touch()
59
- return session
60
-
61
- def check_rate_limit(self, user_id: str) -> bool:
62
- """True if the user is within their hourly budget."""
63
- now = time.time()
64
- log = [t for t in self._request_log.get(user_id, []) if now - t < 3600]
65
- self._request_log[user_id] = log
66
- if len(log) >= self.rate_limit:
67
- return False
68
- log.append(now)
69
- return True
70
-
71
- def _expire(self) -> None:
72
- now = time.time()
73
- stale = [uid for uid, s in self._sessions.items()
74
- if now - s.last_active > self.ttl]
75
- for uid in stale:
76
- del self._sessions[uid]
77
-
78
- def stats(self) -> dict:
79
- return {
80
- "active_sessions": len(self._sessions),
81
- "users": sorted(self._sessions.keys()),
82
- }