From 7e67699d4a43e6ef2f7e9049c533157be3795e09 Mon Sep 17 00:00:00 2001 From: tiino Date: Sun, 17 May 2026 12:29:35 +0900 Subject: [PATCH 1/2] fix(sessions): respect num_recent_events=0 in DatabaseSessionService `DatabaseSessionService.get_session` used a truthy check (`if config and config.num_recent_events:`) which treated `0` as "no limit" and returned all events, contradicting the documented behavior in `GetSessionConfig` ("if 0, no events are returned"). Switch to `is not None` so that `LIMIT 0` is appended for the zero case. Add a boundary assertion to `test_get_session_with_config`, which is parametrized over all four session backends (InMemory, InMemory-light-copy, Database, Sqlite). Closes #5730 --- src/google/adk/sessions/database_session_service.py | 2 +- tests/unittests/sessions/test_session_service.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/google/adk/sessions/database_session_service.py b/src/google/adk/sessions/database_session_service.py index d033f1f234..b36614fd3d 100644 --- a/src/google/adk/sessions/database_session_service.py +++ b/src/google/adk/sessions/database_session_service.py @@ -520,7 +520,7 @@ async def get_session( stmt = stmt.order_by(schema.StorageEvent.timestamp.desc()) - if config and config.num_recent_events: + if config and config.num_recent_events is not None: stmt = stmt.limit(config.num_recent_events) result = await sql_session.execute(stmt) diff --git a/tests/unittests/sessions/test_session_service.py b/tests/unittests/sessions/test_session_service.py index 02f5159a45..b8d5a3c51c 100644 --- a/tests/unittests/sessions/test_session_service.py +++ b/tests/unittests/sessions/test_session_service.py @@ -1067,6 +1067,13 @@ async def test_get_session_with_config(session_service): assert len(events) == num_recent_events assert events[0].timestamp == num_test_events - num_recent_events + 1 + # num_recent_events=0 should return no events (boundary case). + config = GetSessionConfig(num_recent_events=0) + session = await session_service.get_session( + app_name=app_name, user_id=user_id, session_id=session.id, config=config + ) + assert session.events == [] + # Only expect events after timestamp 4.0 (inclusive), i.e., 2 events. after_timestamp = 4.0 config = GetSessionConfig(after_timestamp=after_timestamp) From edce3f54df06f9cfbe5025a13e21c7d39abb792d Mon Sep 17 00:00:00 2001 From: tiino Date: Tue, 19 May 2026 12:32:15 +0900 Subject: [PATCH 2/2] test(sessions): cover num_recent_events=2 and skip query when 0 Address review feedback on #5731 by mirroring the early-return pattern already used in `SqliteSessionService` and `VertexAiSessionService`: when `num_recent_events == 0`, skip the SQLAlchemy `execute()` call entirely instead of issuing a `LIMIT 0` query. This avoids an unnecessary round-trip to the database, which is especially relevant for the remote PostgreSQL / MySQL deployments that `DatabaseSessionService` is primarily designed for. Also extend `test_get_session_with_config` with a `num_recent_events=2` boundary assertion so the test now covers the None / 0 / 2 / 3 cases across all four session backends. --- src/google/adk/sessions/database_session_service.py | 7 +++++-- tests/unittests/sessions/test_session_service.py | 8 ++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/google/adk/sessions/database_session_service.py b/src/google/adk/sessions/database_session_service.py index b36614fd3d..375afc3a7f 100644 --- a/src/google/adk/sessions/database_session_service.py +++ b/src/google/adk/sessions/database_session_service.py @@ -523,8 +523,11 @@ async def get_session( if config and config.num_recent_events is not None: stmt = stmt.limit(config.num_recent_events) - result = await sql_session.execute(stmt) - storage_events = result.scalars().all() + if config and config.num_recent_events == 0: + storage_events = [] + else: + result = await sql_session.execute(stmt) + storage_events = result.scalars().all() # Fetch states from storage storage_app_state = await sql_session.get( diff --git a/tests/unittests/sessions/test_session_service.py b/tests/unittests/sessions/test_session_service.py index b8d5a3c51c..3d2117e805 100644 --- a/tests/unittests/sessions/test_session_service.py +++ b/tests/unittests/sessions/test_session_service.py @@ -1074,6 +1074,14 @@ async def test_get_session_with_config(session_service): ) assert session.events == [] + # num_recent_events=2 should return the 2 most recent events. + config = GetSessionConfig(num_recent_events=2) + session = await session_service.get_session( + app_name=app_name, user_id=user_id, session_id=session.id, config=config + ) + assert len(session.events) == 2 + assert session.events[0].timestamp == num_test_events - 2 + 1 + # Only expect events after timestamp 4.0 (inclusive), i.e., 2 events. after_timestamp = 4.0 config = GetSessionConfig(after_timestamp=after_timestamp)