Robust session id derivation. Priority: 1. previous_response_id chain hit (OpenAI Responses) 2. msg_hashes strict-prefix match in registry 3. fresh id seeded by (first_user_v2, system_hash, metadata_uid, now) `now` is included in the fresh-id seed so two parallel conversa
(
*,
msg_hashes: list[str],
first_user_v2: str,
system_hash: str,
metadata_uid: str,
prev_response: str,
registry: RecentSessions,
now: float,
)
| 123 | |
| 124 | |
| 125 | def derive_session_id_v2( |
| 126 | *, |
| 127 | msg_hashes: list[str], |
| 128 | first_user_v2: str, |
| 129 | system_hash: str, |
| 130 | metadata_uid: str, |
| 131 | prev_response: str, |
| 132 | registry: RecentSessions, |
| 133 | now: float, |
| 134 | ) -> str: |
| 135 | """Robust session id derivation. |
| 136 | |
| 137 | Priority: |
| 138 | 1. previous_response_id chain hit (OpenAI Responses) |
| 139 | 2. msg_hashes strict-prefix match in registry |
| 140 | 3. fresh id seeded by (first_user_v2, system_hash, metadata_uid, now) |
| 141 | |
| 142 | `now` is included in the fresh-id seed so two parallel conversations |
| 143 | starting with identical first messages still get distinct ids. |
| 144 | """ |
| 145 | hashes = tuple(msg_hashes) |
| 146 | |
| 147 | # Eagerly evict stale records before any lookup so TTL is respected. |
| 148 | registry.evict_expired(now) |
| 149 | |
| 150 | # 1. Response-chain rescue. |
| 151 | if prev_response: |
| 152 | chained = registry.find_by_response_id(prev_response) |
| 153 | if chained is not None and chained in registry._records: |
| 154 | rec = registry._records[chained] |
| 155 | rec.msg_hashes = hashes |
| 156 | rec.last_seen_ts = now |
| 157 | registry.upsert(rec) |
| 158 | return chained |
| 159 | |
| 160 | # 2. Prefix match. |
| 161 | match = registry.find_prefix_match(hashes) |
| 162 | if match is not None: |
| 163 | match.msg_hashes = hashes |
| 164 | match.last_seen_ts = now |
| 165 | registry.upsert(match) |
| 166 | return match.session_id |
| 167 | |
| 168 | # 3. Fresh id. |
| 169 | seed = f"{first_user_v2}|{system_hash}|{metadata_uid}".encode("utf-8") |
| 170 | new_sid = hashlib.sha256(seed + str(now).encode("utf-8")).hexdigest()[:8] |
| 171 | registry.upsert( |
| 172 | _SessionRecord(session_id=new_sid, msg_hashes=hashes, last_seen_ts=now) |
| 173 | ) |
| 174 | return new_sid |