aws / aws/bedrock-agentcore-sdk-python
Bug Report: get_last_k_turns() returns messages in reversed order within each turn
- 主要语言
- Python
- 星标
- 761
- 派生
- 147
- 平均合并
- 1 天 23 小时
- 30 天内合并 PR
- 7
描述
# Bug Report: `get_last_k_turns()` returns messages in reversed order within each turn
**Reporter**: Amazon Employee (not a team member of AgentCore SDK, reporting issue only)
## Description
`get_last_k_turns()` returns turns with messages in reversed order (ASSISTANT before USER) instead of chronological order (USER before ASSISTANT). This contradicts the docstring which states "A turn typically consists of a user message followed by assistant response(s)."
## Environment
- **OS**: macOS
- **Python version**: 3.12
- **SDK version**: 1.2.0, 1.2.1 (tested both - bug persists)
- **AWS Region**: ap-northeast-2
## Steps to Reproduce
```python
from bedrock_agentcore.memory import MemoryClient, MemorySessionManager
memory_client = MemoryClient(region_name="ap-northeast-2")
session_manager = MemorySessionManager(
memory_id="mem-xxxxxxxx",
region_name="ap-northeast-2",
)
# Create events in chronological order
# Event 1: USER "Hello"
# Event 2: ASSISTANT "Hi there!"
# Event 3: USER "What's the weather?"
# Event 4: ASSISTANT [toolUse: get_weather]
# Event 5: USER [toolResult: sunny]
# Event 6: ASSISTANT "It's sunny today"
# Get last k turns
turns = session_manager.get_last_k_turns(
actor_id="user_001",
session_id="session_001",
k=10
)
print(turns)
```
## Expected Behavior
Each turn should have messages in chronological order (USER first, then ASSISTANT):
```python
[
[{'role': 'USER', 'content': ...}, {'role': 'ASSISTANT', 'content': ...}],
[{'role': 'USER', 'content': ...}, {'role': 'ASSISTANT', 'content': ...}],
...
]
```
## Actual Behavior
Each turn has messages in **reversed order** (ASSISTANT first, then USER):
```python
[
[{'role': 'ASSISTANT', 'content': "서울역[1호선]으로 안내를..."}], # Turn with only ASSISTANT
[{'role': 'USER', 'content': ...toolResult...}, {'role': 'ASSISTANT', 'content': ...toolUse...}], # Reversed!
[{'role': 'USER', 'content': "2번"}, {'role': 'ASSISTANT', 'content': "서울역 5곳이에요..."}], # Looks correct but paired with PREVIOUS assistant response
...
]
```
## Root Cause Analysis
Looking at the SDK source code in `client.py`:
```python
def get_last_k_turns(self, ...):
# ...
response = self.gmdp_client.list_events(**params) # Returns events in reverse chronological order (newest first)
events = response.get("events", [])
for event in events: # Iterates in reverse order without sorting
# ...
if role == Role.USER.value and current_turn:
turns.append(current_turn)
current_turn = []
current_turn.append(payload_item["conversational"])
```
The issue is that `list_events` API returns events in **reverse chronological order** (newest first), but the SDK processes them without sorting to chronological order first.
## Suggested Fix
Sort events by `eventTimestamp` before processing:
```python
def get_last_k_turns(self, ...):
# ... fetch events ...
# Sort events chronologically before processing
all_events = sorted(all_events, key=lambda e: e.get('eventTimestamp', ''))
# Then process turns...
```
Or reverse the events list before iteration:
```python
for event in reversed(events): # Process oldest to newest
```
## Impact
This bug affects any application that relies on `get_last_k_turns()` to retrieve conversation history for:
- Passing to LLM as context (messages appear in wrong order)
- Displaying conversation history to users
- Analyzing conversation flow
## Workaround
Currently using `list_events()` and manually sorting/grouping:
```python
events = session_manager.list_events(actor_id, session_id)
events_sorted = sorted(events, key=lambda e: e['eventTimestamp'])
# Manual turn grouping...
```
## Related
- PR #209 improved pagination but did not address the ordering issue
- The docstring says "user message followed by assistant response(s)" but actual behavior is reversed
## Update Log
### 2026-02-05: Tested with SDK 1.2.1
Bug still persists in version 1.2.1. Test results:
```
SDK Version: 1.2.1
============================================================
각 턴의 메시지 순서 확인:
============================================================
Turn 1: ['ASSISTANT'] # ← Only ASSISTANT, no USER
Turn 2: ['USER', 'ASSISTANT'] # ← Looks correct but actually misaligned
Turn 3: ['USER', 'ASSISTANT']
Turn 4: ['USER', 'ASSISTANT']
Turn 5: ['USER', 'ASSISTANT']
```
The issue is that Turn 1 contains only ASSISTANT (orphaned from its USER), and subsequent turns pair the PREVIOUS assistant response with the CURRENT user message - the entire conversation is shifted by one position.
贡献指南
调研方向
从 client.py 中的 get_last_k_turns 开始,使用 list_events 或提供的 MemorySessionManager 示例重现所提供的事件序列。验证返回的轮次是否保留按时间顺序排列的 USER-before-ASSISTANT 顺序,以及响应是否与正确的用户消息配对。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- aws, python
- 领域
- api, backend
- Issue 类型
- 缺陷
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 活跃度
- 停滞
- 描述清晰度
- 描述清楚
- 新手友好度
- 50/100