Support paginated thread history in app-server list APIs (#33152)

## Why

Clients could discover threads with paginated history, but could not page their
turns through `thread/turns/list`.

## What changed

- Route `thread/turns/list` for paginated threads through the thread store,
  preserving cursors, sort direction, turn status, timing, errors, and the
  requested `summary` or `notLoaded` item view.
- Reject the `full` turn item view for paginated threads and direct clients to
  `thread/items/list` for complete item pagination.
- Return each item page entry with both its containing `turnId` and `item`, so
  clients can regroup thread-wide pages into turns.
- Expose local thread-store turn and item pagination through the `ThreadStore`
  implementation.

## Testing

Added app-server coverage for paging projected turns and items, item views,
cursors, turn metadata, and rejection of the unsupported `full` view.

GitOrigin-RevId: 9c4a127a9b4fa91313f0e87494c62fe2e3a06f19
This commit is contained in:
Owen Lin authored and copyberry committed 2026-07-14 20:48:05 +00:00
1 parent 4da39dbea7
commit e0a3641e6c
11 files changed
+532 -19

No files matched your search

@@ -256,8 +256,11 @@ fn thread_items_list_round_trips() {
})
);
let response = ThreadItemsListResponse {
data: vec![ThreadItem::ContextCompaction {
id: "item_1".to_string(),
data: vec![ThreadItemEntry {
turn_id: "turn_456".to_string(),
item: ThreadItem::ContextCompaction {
id: "item_1".to_string(),
},
}],
next_cursor: None,
backwards_cursor: Some("cursor_0".to_string()),
@@ -266,7 +269,10 @@ fn thread_items_list_round_trips() {
assert_eq!(
serde_json::to_value(&response).expect("serialize response"),
json!({
"data": [{"type": "contextCompaction", "id": "item_1"}],
"data": [{
"turnId": "turn_456",
"item": {"type": "contextCompaction", "id": "item_1"},
}],
"nextCursor": null,
"backwardsCursor": "cursor_0",
})