mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-31 00:03:01 +03:00
fix(session): clear file state at deletion boundary
This commit is contained in:
@@ -377,11 +377,15 @@ class AgentLoop:
|
||||
|
||||
self.context = ContextBuilder(workspace, timezone=timezone, disabled_skills=disabled_skills)
|
||||
self.sessions = session_manager or SessionManager(workspace)
|
||||
self.sessions.set_file_cap_archiver(self.context.memory.raw_archive)
|
||||
self.tools = tool_registry if tool_registry is not None else ToolRegistry()
|
||||
# One file-read/write tracker per logical session. The tool registry is
|
||||
# shared by this loop, so tools resolve the active state via contextvars.
|
||||
self._file_state_store = FileStateStore(max_sessions=SESSION_CACHE_MAX_SIZE)
|
||||
# SessionManager owns every durable deletion entrypoint, including the
|
||||
# WebUI and fork rollback paths. Observe that boundary once instead of
|
||||
# duplicating cleanup in each consumer.
|
||||
self.sessions.set_delete_observer(self._file_state_store.discard)
|
||||
self.sessions.set_file_cap_archiver(self.context.memory.raw_archive)
|
||||
self.tools = tool_registry if tool_registry is not None else ToolRegistry()
|
||||
self._exec_session_manager = ExecSessionManager()
|
||||
self.runner = AgentRunner()
|
||||
self.subagents = SubagentManager(
|
||||
|
||||
@@ -146,7 +146,6 @@ class SessionClient:
|
||||
|
||||
def delete(self, session_key: str) -> bool:
|
||||
"""Delete one session from disk and cache."""
|
||||
self._loop.discard_session_file_state(session_key)
|
||||
return self._loop.sessions.delete_session(session_key)
|
||||
|
||||
def flush(self) -> int:
|
||||
|
||||
@@ -1523,6 +1523,7 @@ class SessionManager:
|
||||
self._overflow_cache: WeakValueDictionary[str, Session] = WeakValueDictionary()
|
||||
self._max_cached_sessions = SESSION_CACHE_MAX_SIZE
|
||||
self._file_cap_archiver: Callable[..., None] | None = None
|
||||
self._delete_observer: Callable[[str], None] | None = None
|
||||
|
||||
def _remember(self, session: Session) -> None:
|
||||
"""Keep recent sessions strongly cached without duplicating live objects."""
|
||||
@@ -1552,6 +1553,10 @@ class SessionManager:
|
||||
"""Archive unconsolidated overflow whenever a session is persisted."""
|
||||
self._file_cap_archiver = archiver
|
||||
|
||||
def set_delete_observer(self, observer: Callable[[str], None]) -> None:
|
||||
"""Observe explicit session deletion for process-local state cleanup."""
|
||||
self._delete_observer = observer
|
||||
|
||||
@staticmethod
|
||||
def safe_key(key: str) -> str:
|
||||
"""Public helper used by HTTP handlers to map an arbitrary key to a stable filename stem."""
|
||||
@@ -1684,7 +1689,10 @@ class SessionManager:
|
||||
def delete_session(self, key: str) -> bool:
|
||||
"""Delete a persisted session and invalidate its cache entry."""
|
||||
self.invalidate(key)
|
||||
return self._store.delete(key)
|
||||
deleted = self._store.delete(key)
|
||||
if self._delete_observer is not None:
|
||||
self._delete_observer(key)
|
||||
return deleted
|
||||
|
||||
def restore_sessions_to_workspace(self) -> SessionRestoreResult:
|
||||
"""Restore session files to the pre-relocation path for an explicit rollback."""
|
||||
|
||||
@@ -34,6 +34,17 @@ def test_delete_session_returns_false_when_missing(tmp_path: Path) -> None:
|
||||
assert sm.delete_session("nope:none") is False
|
||||
|
||||
|
||||
def test_delete_session_notifies_process_local_state_observer(tmp_path: Path) -> None:
|
||||
sm = _seed(tmp_path, "websocket:abc")
|
||||
deleted_keys: list[str] = []
|
||||
sm.set_delete_observer(deleted_keys.append)
|
||||
|
||||
assert sm.delete_session("websocket:abc") is True
|
||||
assert sm.delete_session("websocket:missing") is False
|
||||
|
||||
assert deleted_keys == ["websocket:abc", "websocket:missing"]
|
||||
|
||||
|
||||
def test_read_session_file_returns_metadata_and_messages(tmp_path: Path) -> None:
|
||||
sm = _seed(tmp_path, "telegram:abc")
|
||||
data = sm.read_session_file("telegram:abc")
|
||||
|
||||
Reference in New Issue
Block a user