Skip to content

fix(memory): Improve pagination behavior in get_last_k_turns() and list_messages() - #209

Merged
aidandaly24 merged 4 commits into
aws:mainfrom
kevmyung:fix/pagination-behavior
Jan 13, 2026
Merged

fix(memory): Improve pagination behavior in get_last_k_turns() and list_messages()#209
aidandaly24 merged 4 commits into
aws:mainfrom
kevmyung:fix/pagination-behavior

Conversation

@kevmyung

@kevmyung kevmyung commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • get_last_k_turns() in both MemoryClient and MemorySessionManager now automatically paginates until k turns are found when max_results is not specified
  • list_messages() in AgentCoreMemorySessionManager adds fetch_all parameter to retrieve all messages instead of being limited to 100
  • Maintains backward compatibility: existing code with explicit max_results parameter behaves the same

Problem

Previously, get_last_k_turns(k=200) would only fetch 100 events (the default max_results) regardless of the k value requested. This caused issues when users needed more than 100 events worth of conversation turns.

Similarly, list_messages(limit=None) was hardcoded to return only 100 messages, making it impossible to retrieve all messages in a session.

Changes

client.py & session.py

  • Changed max_results default from 100 to None
  • When max_results=None, automatically paginates until k turns are found
  • When max_results is explicitly provided, respects that limit (backward compatible)

strands/session_manager.py

  • Added fetch_all: bool = False parameter to list_messages()
  • When fetch_all=True, fetches up to 10,000 messages

Tests

  • Added test_get_last_k_turns_auto_pagination - verifies pagination continues until k turns found
  • Added test_get_last_k_turns_explicit_max_results - verifies backward compatibility
  • Added test_list_messages_fetch_all - verifies fetch_all parameter works correctly

Test plan

  • Unit tests pass (pytest tests/bedrock_agentcore/memory/)
  • Manual integration test with actual Amazon AgentCore Memory

Closes #206

@kevmyung
kevmyung temporarily deployed to manual-approval January 9, 2026 00:35 — with GitHub Actions Inactive
# Process events to group into turns
turns = []
current_turn = []
next_token = None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (non-blocking): This pagination logic (lines 805-857) is nearly identical to client.py lines 1108-1157. Consider extracting into a shared helper to reduce duplication and maintenance burden. Future bug fixes would need to be applied to both locations otherwise.

"""Test get_last_k_turns auto-calculates max_results based on k."""
with patch("boto3.Session") as mock_boto_client:
mock_client_instance = MagicMock()
mock_boto_client.return_value = mock_client_instance

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: This test mocks manager.list_events, but the new implementation in session.py no longer calls list_events() - it directly calls self._data_plane_client.list_events(). This mock won't intercept the actual calls.

Should mock manager._data_plane_client.list_events instead, similar to how test_client.py mocks client.gmdp_client.list_events.

try:
max_results = (limit + offset) if limit else 100
if fetch_all:
max_results = 10000

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: The value 10000 is a magic number. Consider extracting to a named constant (e.g., MAX_FETCH_ALL_RESULTS = 10000) for clarity and maintainability.

@@ -786,52 +786,82 @@
k: int = 5,
branch_name: Optional[str] = None,
include_parent_branches: bool = False,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought: client.py uses include_branches while session.py uses include_parent_branches. This inconsistency predates this PR but is worth noting for future cleanup.

kevmyung and others added 2 commits January 12, 2026 17:05
…ist_messages()

- get_last_k_turns(): Auto-calculate max_results based on k (max(100, k*3))
- list_messages(): Add fetch_all parameter to fetch all messages (up to 10000)
- Backward compatible: default behavior unchanged
- Extract shared pagination logic into pagination.py helper
- Fix test mocks to use _data_plane_client.list_events
- Add MAX_FETCH_ALL_RESULTS constant (10000) in strands session_manager
- Rename include_branches to include_parent_branches in client.py for consistency
- Add comprehensive tests for pagination helper
agent_id: str,
limit: Optional[int] = None,
offset: int = 0,
fetch_all: bool = False,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For fetch_all, we aren't really fetching all issue, just whatever MAX_FETCH_ALL_RESULTS is. Therefore, we should just remove this field.

raise SessionException(f"Session ID mismatch: expected {self.config.session_id}, got {session_id}")

try:
max_results = (limit + offset) if limit else 100

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep this line but have MAX_FETCH_ALL_RESULTS which is 10000

logger = logging.getLogger(__name__)


def paginate_turns(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really seeing anyone using this function besides MemoryClient and Session class. I would either move into either class or both classes.

Comment thread src/bedrock_agentcore/memory/client.py Outdated
branch_name: Optional[str] = None,
include_branches: bool = False,
max_results: int = 100,
include_parent_branches: bool = False,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If include_branches is already commited in the code, renaming this will introduce a breaking change

- Remove fetch_all parameter from list_messages (misleading name)
- Use MAX_FETCH_ALL_RESULTS (10000) as default when no limit specified
- Remove pagination.py module, inline logic into client.py and session.py
- Revert include_branches rename to avoid breaking change
@codecov-commenter

codecov-commenter commented Jan 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.81818% with 12 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@0df9757). Learn more about missing BASE report.

Files with missing lines Patch % Lines
src/bedrock_agentcore/memory/client.py 77.77% 2 Missing and 4 partials ⚠️
src/bedrock_agentcore/memory/session.py 83.78% 2 Missing and 4 partials ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #209   +/-   ##
=======================================
  Coverage        ?   90.50%           
=======================================
  Files           ?       35           
  Lines           ?     3412           
  Branches        ?      507           
=======================================
  Hits            ?     3088           
  Misses          ?      179           
  Partials        ?      145           
Flag Coverage Δ
unittests 90.50% <81.81%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

jariy17
jariy17 previously approved these changes Jan 13, 2026
Apply automatic formatting fixes identified by ruff format pre-commit hook.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

@aidandaly24 aidandaly24 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jariy17
jariy17 temporarily deployed to manual-approval January 13, 2026 21:51 — with GitHub Actions Inactive
@aidandaly24
aidandaly24 merged commit 2b047ff into aws:main Jan 13, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve pagination behavior in get_last_k_turns() and list_messages()

4 participants