mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Add persisted thread pinning to the app server (#34840)
## What changed - Add `isPinned` to thread responses and allow `thread/metadata/update` to pin or unpin stored threads. - Add an `isPinned` filter to `thread/list`, including cursor-based pagination and combinations with relationship filters. - Persist pin state in SQLite without modifying rollout files, default existing threads to unpinned, and preserve pins through reconciliation and archive transitions. ## Testing - Cover protocol serialization, database migration and indexing, pin updates, filtered pagination, rollout reconciliation, and archive/unarchive behavior. GitOrigin-RevId: c2eacabd6dae465e2ae6ce8a169e00740960cdb7
This commit is contained in:
1 parent
d7e8f4c3dc
commit
400ee190c3
71 files changed
+1058
-60
No files matched your search
@@ -1,13 +1,12 @@
|
||||
use codex_rollout::find_archived_thread_path_by_id_str;
|
||||
use codex_rollout::read_thread_item_from_rollout;
|
||||
use codex_rollout::rollout_date_parts;
|
||||
|
||||
use super::LocalThreadStore;
|
||||
use super::helpers::matching_rollout_file_name;
|
||||
use super::helpers::scoped_rollout_path;
|
||||
use super::helpers::stored_thread_from_rollout_item;
|
||||
use super::helpers::touch_modified_time;
|
||||
use crate::ArchiveThreadParams;
|
||||
use crate::ReadThreadParams;
|
||||
use crate::StoredThread;
|
||||
use crate::ThreadStoreError;
|
||||
use crate::ThreadStoreResult;
|
||||
@@ -79,25 +78,15 @@ pub(super) async fn unarchive_thread(
|
||||
.await;
|
||||
}
|
||||
|
||||
let item = read_thread_item_from_rollout(restored_path.clone())
|
||||
.await
|
||||
.ok_or_else(|| ThreadStoreError::Internal {
|
||||
message: format!(
|
||||
"failed to read unarchived thread {}",
|
||||
restored_path.display()
|
||||
),
|
||||
})?;
|
||||
stored_thread_from_rollout_item(
|
||||
item,
|
||||
/*archived*/ false,
|
||||
store.config.default_model_provider_id.as_str(),
|
||||
super::read_thread::read_thread(
|
||||
store,
|
||||
ReadThreadParams {
|
||||
thread_id,
|
||||
include_archived: false,
|
||||
include_history: false,
|
||||
},
|
||||
)
|
||||
.ok_or_else(|| ThreadStoreError::Internal {
|
||||
message: format!(
|
||||
"failed to read unarchived thread id from {}",
|
||||
restored_path.display()
|
||||
),
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -175,15 +164,17 @@ mod tests {
|
||||
builder.cli_version = Some("test_version".to_string());
|
||||
let mut metadata = builder.build(config.default_model_provider_id.as_str());
|
||||
metadata.archived_at = Some(metadata.updated_at);
|
||||
metadata.is_pinned = true;
|
||||
runtime
|
||||
.upsert_thread(&metadata)
|
||||
.await
|
||||
.expect("state db upsert should succeed");
|
||||
|
||||
store
|
||||
let unarchived = store
|
||||
.unarchive_thread(ArchiveThreadParams { thread_id })
|
||||
.await
|
||||
.expect("unarchive thread");
|
||||
assert!(unarchived.is_pinned);
|
||||
|
||||
let restored_path = home
|
||||
.path()
|
||||
@@ -197,5 +188,6 @@ mod tests {
|
||||
assert_eq!(updated.rollout_path, restored_path);
|
||||
assert_eq!(updated.archived_at, None);
|
||||
assert_eq!(updated.recency_at, metadata.recency_at);
|
||||
assert!(updated.is_pinned);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user