aws / aws/bedrock-agentcore-sdk-python

Bug Report: get_last_k_turns() returns messages in reversed order within each turn

Đang mở
#253 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
memory
Ngôn ngữ chính
Python
Star
761
Fork
147
Merge trung bình
1 ngày 23 giờ
Pull request đã merge (30 ngày)
7

Mô tả

# 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.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Bắt đầu trong client.py tại get_last_k_turns và tái hiện chuỗi sự kiện được cung cấp bằng list_events hoặc ví dụ MemorySessionManager được cung cấp. Xác minh rằng các lượt trả về vẫn giữ thứ tự thời gian USER-before-ASSISTANT và các phản hồi được ghép đúng với các tin nhắn người dùng tương ứng.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
aws, python
Lĩnh vực
api, backend
Loại issue
Lỗi
Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
50/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.