From 8dfce4c162c8483fd59ccfbb96c1b0e0af10c751 Mon Sep 17 00:00:00 2001 From: chengyongru Date: Fri, 7 Aug 2026 10:28:59 +0800 Subject: [PATCH] fix(session): require user anchor for delivery retention --- nanobot/session/manager.py | 10 ++++++---- tests/agent/test_session_retention.py | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/nanobot/session/manager.py b/nanobot/session/manager.py index 65d9b58f2..86ab3bc7a 100644 --- a/nanobot/session/manager.py +++ b/nanobot/session/manager.py @@ -352,12 +352,14 @@ class Session: start_idx = max(0, len(self.messages) - max_messages) if extend_to_user: - start_idx = next( + recovered_user = next( (i for i in range(start_idx, -1, -1) if self.messages[i].get("role") == "user"), - start_idx, + None, ) - if start_idx > 0 and self.messages[start_idx - 1].get("_channel_delivery"): - start_idx -= 1 + if recovered_user is not None: + start_idx = recovered_user + if start_idx > 0 and self.messages[start_idx - 1].get("_channel_delivery"): + start_idx -= 1 retained = self.messages[start_idx:] diff --git a/tests/agent/test_session_retention.py b/tests/agent/test_session_retention.py index e0f245ece..f35e23e41 100644 --- a/tests/agent/test_session_retention.py +++ b/tests/agent/test_session_retention.py @@ -120,6 +120,20 @@ def test_retain_extend_to_user_matches_get_history_boundary(): assert _contents(session.messages) == _contents(expected) +def test_retain_extend_to_user_does_not_extend_delivery_only_tail(): + session = Session(key="test:extend-no-user") + for i in range(4): + session.messages.append(_delivery(f"notification {i}")) + + session.retain_recent_legal_suffix(3, extend_to_user=True) + + assert _contents(session.messages) == [ + "notification 1", + "notification 2", + "notification 3", + ] + + # --- Only the immediately-preceding delivery is part of the anchor ---