fix: harden tooling session reuse and event routing
Ensure session reuse is disabled for tooling contexts, include tool config in cache keys, and stabilize tool event merge/routing with expanded bridge tests. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import hashlib
|
||||
import json
|
||||
import time
|
||||
from collections import OrderedDict
|
||||
from dataclasses import dataclass
|
||||
@@ -42,6 +43,16 @@ def hash_user_context(messages: list[dict]) -> str:
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def _tool_fingerprint(tool_config: dict | None) -> str:
|
||||
if not isinstance(tool_config, dict):
|
||||
return "-"
|
||||
try:
|
||||
canonical = json.dumps(tool_config, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
|
||||
except Exception:
|
||||
canonical = str(tool_config)
|
||||
return hashlib.sha1(canonical.encode("utf-8")).hexdigest()[:16]
|
||||
|
||||
|
||||
class SessionCache:
|
||||
"""LRU + TTL cache: conversation-prefix hash -> upstream Lingma sessionId.
|
||||
|
||||
@@ -79,11 +90,11 @@ class SessionCache:
|
||||
def enabled(self) -> bool:
|
||||
return self.max > 0
|
||||
|
||||
def build_key(self, api_key: str, messages: list[dict]) -> str:
|
||||
def build_key(self, api_key: str, messages: list[dict], *, tool_config: dict | None = None) -> str:
|
||||
# API key scoping prevents cross-tenant session leakage even when
|
||||
# different clients happen to produce identical histories.
|
||||
key_scope = hashlib.sha1((api_key or "-").encode("utf-8")).hexdigest()[:12]
|
||||
return f"{key_scope}:{hash_user_context(messages)}"
|
||||
return f"{key_scope}:{hash_user_context(messages)}:{_tool_fingerprint(tool_config)}"
|
||||
|
||||
async def get(self, key: str) -> SessionEntry | None:
|
||||
if not self.enabled:
|
||||
|
||||
Reference in New Issue
Block a user