Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/google/adk/events/_rewind_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,13 @@ def _apply_rewinds(events: list[Event]) -> list[Event]:
rewind_idx = first_idx_by_inv.get(
event.actions.rewind_before_invocation_id
)
if rewind_idx is not None and rewind_idx < i:
if rewind_idx is None:
# Target is not in `events` — either an unknown id, or the list was
# truncated by GetSessionConfig.num_recent_events / after_timestamp
# so the target fell outside the window. Everything earlier in this
# list belongs to the rewound span; stop so those events stay out.
break
if rewind_idx < i:
i = rewind_idx
else:
kept.append(event)
Expand Down
22 changes: 20 additions & 2 deletions tests/unittests/events/test_rewind_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,28 @@ def test_get_active_events_rewind_target_not_found():
)

events = [event_a, rewind_event]
# Target missing from the list (unknown id or truncated window): drop
# every earlier event so rewound turns cannot leak into a prompt.
assert get_active_events(events) == []


def test_get_active_events_rewind_target_outside_window():
"""num_recent_events can omit the rewind target; later turns must still drop."""
event_b = _make_event("inv-2", "user")
event_b_ok = _make_event("inv-2", "agent")
rewind_event = _make_event(
"inv-rewind", "user", rewind_before_invocation_id="inv-1"
)
event_c = _make_event("inv-3", "user")
event_c_ok = _make_event("inv-3", "agent")

# Window starts at inv-2; inv-1 (the rewind target) is not loaded.
events = [event_b, event_b_ok, rewind_event, event_c, event_c_ok]
result = get_active_events(events)

assert len(result) == 1
assert result[0] is event_a
assert len(result) == 2
assert result[0] is event_c
assert result[1] is event_c_ok


def test_get_active_events_preserves_chronological_order():
Expand Down
Loading