From 298b7ac6f68721e613cfb669a9515aec93d1e3d6 Mon Sep 17 00:00:00 2001 From: nanobot Date: Fri, 31 Jul 2026 15:49:31 +0800 Subject: [PATCH] fix: use dedicated _shutting_down flag for cancel-time checkpoint restore The previous guard used self._running, which is False both before run() starts and during shutdown. Tests and process_direct() dispatch messages with _running=False, so cancelled turns there silently skipped the checkpoint restore and lost partial context. Introduce _shutting_down, set only by stop(), and gate the restore on it. --- nanobot/agent/loop.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/nanobot/agent/loop.py b/nanobot/agent/loop.py index 5606230a..17a28c49 100644 --- a/nanobot/agent/loop.py +++ b/nanobot/agent/loop.py @@ -378,6 +378,7 @@ class AgentLoop: ) self._unified_session = unified_session self._running = False + self._shutting_down = False self._mcp_servers = mcp_servers or {} self._mcp_stacks: dict[str, MCPConnection] = {} self._mcp_connecting = False @@ -1224,11 +1225,11 @@ class AgentLoop: # it into session history now makes it visible in the # next conversation turn. # - # During gateway shutdown (self._running is False), skip - # this so the pending markers survive and + # During gateway shutdown (self._shutting_down is True), + # skip this so the pending markers survive and # recover_stale_sessions() can notify the user and # re-trigger the interrupted turn on next startup. - if self._running: + if not self._shutting_down: try: key = self._effective_session_key(msg) session = self.sessions.get_or_create(key) @@ -1318,6 +1319,7 @@ class AgentLoop: def stop(self) -> None: """Stop the agent loop.""" self._running = False + self._shutting_down = True logger.info("Agent loop stopping") async def _process_message(