mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Add sorting/backwardsCursor to thread/list and new thread/turns/list api (#17305)
To improve performance of UI loads from the app, add two main improvements: 1. The `thread/list` api now gets a `sortDirection` request field and a `backwardsCursor` to the response, which lets you paginate forwards and backwards from a window. This lets you fetch the first few items to display immediately while you paginate to fill in history, then can paginate "backwards" on future loads to catch up with any changes since the last UI load without a full reload of the entire data set. 2. Added a new `thread/turns/list` api which also has sortDirection and backwardsCursor for the same behavior as `thread/list`, allowing you the same small-fetch for immediate display followed by background fill-in and resync catchup.
This commit is contained in:
1 parent
29bc2ad2f4
commit
eaf78e43f2
54 files changed
+3510
-219
No files matched your search
@@ -707,8 +707,7 @@ async fn test_pagination_cursor() {
|
||||
.join(format!("rollout-2025-03-04T09-00-00-{u4}.jsonl"));
|
||||
let updated_page1: Vec<Option<String>> =
|
||||
page1.items.iter().map(|i| i.updated_at.clone()).collect();
|
||||
let expected_cursor1: Cursor =
|
||||
serde_json::from_str(&format!("\"2025-03-04T09-00-00|{u4}\"")).unwrap();
|
||||
let expected_cursor1: Cursor = serde_json::from_str("\"2025-03-04T09-00-00\"").unwrap();
|
||||
let expected_page1 = ThreadsPage {
|
||||
items: vec![
|
||||
ThreadItem {
|
||||
@@ -775,8 +774,7 @@ async fn test_pagination_cursor() {
|
||||
.join(format!("rollout-2025-03-02T09-00-00-{u2}.jsonl"));
|
||||
let updated_page2: Vec<Option<String>> =
|
||||
page2.items.iter().map(|i| i.updated_at.clone()).collect();
|
||||
let expected_cursor2: Cursor =
|
||||
serde_json::from_str(&format!("\"2025-03-02T09-00-00|{u2}\"")).unwrap();
|
||||
let expected_cursor2: Cursor = serde_json::from_str("\"2025-03-02T09-00-00\"").unwrap();
|
||||
let expected_page2 = ThreadsPage {
|
||||
items: vec![
|
||||
ThreadItem {
|
||||
@@ -1207,7 +1205,7 @@ async fn test_updated_at_uses_file_mtime() -> Result<()> {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_stable_ordering_same_second_pagination() {
|
||||
async fn test_timestamp_only_cursor_skips_same_second_filesystem_ties() {
|
||||
let temp = TempDir::new().unwrap();
|
||||
let home = temp.path();
|
||||
|
||||
@@ -1268,7 +1266,7 @@ async fn test_stable_ordering_same_second_pagination() {
|
||||
.join(format!("rollout-2025-07-01T00-00-00-{u2}.jsonl"));
|
||||
let updated_page1: Vec<Option<String>> =
|
||||
page1.items.iter().map(|i| i.updated_at.clone()).collect();
|
||||
let expected_cursor1: Cursor = serde_json::from_str(&format!("\"{ts}|{u2}\"")).unwrap();
|
||||
let expected_cursor1: Cursor = serde_json::from_str(&format!("\"{ts}\"")).unwrap();
|
||||
let expected_page1 = ThreadsPage {
|
||||
items: vec![
|
||||
ThreadItem {
|
||||
@@ -1321,33 +1319,12 @@ async fn test_stable_ordering_same_second_pagination() {
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let p1 = home
|
||||
.join("sessions")
|
||||
.join("2025")
|
||||
.join("07")
|
||||
.join("01")
|
||||
.join(format!("rollout-2025-07-01T00-00-00-{u1}.jsonl"));
|
||||
let updated_page2: Vec<Option<String>> =
|
||||
page2.items.iter().map(|i| i.updated_at.clone()).collect();
|
||||
// The filesystem fallback only has second-precision timestamps in filenames. The primary
|
||||
// SQLite-backed listing uses unique millisecond timestamps and does not have this tie.
|
||||
let expected_page2 = ThreadsPage {
|
||||
items: vec![ThreadItem {
|
||||
path: p1,
|
||||
thread_id: Some(thread_id_from_uuid(u1)),
|
||||
first_user_message: Some("Hello from user".to_string()),
|
||||
cwd: Some(Path::new(".").to_path_buf()),
|
||||
git_branch: None,
|
||||
git_sha: None,
|
||||
git_origin_url: None,
|
||||
source: Some(SessionSource::VSCode),
|
||||
agent_nickname: None,
|
||||
agent_role: None,
|
||||
model_provider: Some(TEST_PROVIDER.to_string()),
|
||||
cli_version: Some("test_version".to_string()),
|
||||
created_at: Some(ts.to_string()),
|
||||
updated_at: updated_page2.first().cloned().flatten(),
|
||||
}],
|
||||
items: Vec::new(),
|
||||
next_cursor: None,
|
||||
num_scanned_files: 3, // scanned u3, u2 (anchor), u1
|
||||
num_scanned_files: 3,
|
||||
reached_scan_cap: false,
|
||||
};
|
||||
assert_eq!(page2, expected_page2);
|
||||
|
||||
Reference in new issue
Block a user