[thread-store] add updated item list API

This commit is contained in:
Richard Lee
2026-07-06 10:47:41 -07:00
parent 8268cbfb0e
commit df70ca822a
4 changed files with 74 additions and 0 deletions

View File

@@ -52,6 +52,7 @@ mod tests {
use super::*;
use crate::ListItemsParams;
use crate::ListTurnsParams;
use crate::ListUpdatedItemsParams;
use crate::SortDirection;
use crate::StoredTurnItemsView;
use crate::ThreadPersistenceMetadata;
@@ -99,6 +100,25 @@ mod tests {
operation: "list_items"
}
));
let updated_items_err = store
.list_updated_items(ListUpdatedItemsParams {
thread_id,
turn_id: None,
after_updated_at: None,
through_updated_at: None,
cursor: None,
page_size: 10,
sort_direction: SortDirection::Asc,
})
.await
.expect_err("default list_updated_items should be unsupported");
assert!(matches!(
updated_items_err,
ThreadStoreError::Unsupported {
operation: "list_updated_items"
}
));
}
#[tokio::test]

View File

@@ -33,6 +33,7 @@ pub use types::ItemPage;
pub use types::ListItemsParams;
pub use types::ListThreadsParams;
pub use types::ListTurnsParams;
pub use types::ListUpdatedItemsParams;
pub use types::LoadThreadHistoryParams;
pub use types::ReadThreadByRolloutPathParams;
pub use types::ReadThreadParams;
@@ -55,3 +56,4 @@ pub use types::ThreadSearchPage;
pub use types::ThreadSortKey;
pub use types::TurnPage;
pub use types::UpdateThreadMetadataParams;
pub use types::UpdatedItemsPage;

View File

@@ -12,6 +12,7 @@ use crate::ItemPage;
use crate::ListItemsParams;
use crate::ListThreadsParams;
use crate::ListTurnsParams;
use crate::ListUpdatedItemsParams;
use crate::LoadThreadHistoryParams;
use crate::ReadThreadByRolloutPathParams;
use crate::ReadThreadParams;
@@ -25,6 +26,7 @@ use crate::ThreadStoreError;
use crate::ThreadStoreResult;
use crate::TurnPage;
use crate::UpdateThreadMetadataParams;
use crate::UpdatedItemsPage;
/// Future returned by [`ThreadStore`] operations.
pub type ThreadStoreFuture<'a, T> = Pin<Box<dyn Future<Output = ThreadStoreResult<T>> + Send + 'a>>;
@@ -120,6 +122,18 @@ pub trait ThreadStore: Any + Send + Sync {
})
}
/// Lists latest item snapshots changed within a timestamp-bounded interval.
fn list_updated_items(
&self,
_params: ListUpdatedItemsParams,
) -> ThreadStoreFuture<'_, UpdatedItemsPage> {
Box::pin(async {
Err(ThreadStoreError::Unsupported {
operation: "list_updated_items",
})
})
}
/// Applies a literal metadata patch and returns the updated thread.
///
/// Implementations should apply the supplied fields directly. Policy such as deciding whether

View File

@@ -389,6 +389,30 @@ pub struct ListItemsParams {
pub sort_direction: SortDirection,
}
/// Parameters for listing items changed within a timestamp-bounded interval.
///
/// When both bounds are present, implementations should interpret the interval as
/// `(after_updated_at, through_updated_at]`. Bounds remain optional so each store owns validation
/// of partial ranges. Callers should use [`crate::ThreadStore::list_items`] when neither bound is
/// present, and must reuse the same bounds when following a page cursor.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ListUpdatedItemsParams {
/// Thread id to read.
pub thread_id: ThreadId,
/// Optional turn id to filter by. When omitted, returns items across the thread.
pub turn_id: Option<String>,
/// Exclusive lower bound for item updates.
pub after_updated_at: Option<DateTime<Utc>>,
/// Inclusive upper bound for item updates.
pub through_updated_at: Option<DateTime<Utc>>,
/// Opaque cursor returned by a previous list call.
pub cursor: Option<String>,
/// Maximum number of items to return.
pub page_size: usize,
/// Sort direction requested by the caller.
pub sort_direction: SortDirection,
}
/// A projected app-server `ThreadItem` snapshot within a turn.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct StoredThreadItem {
@@ -410,6 +434,20 @@ pub struct ItemPage {
pub backwards_cursor: Option<String>,
}
/// A page of items changed within a timestamp-bounded interval.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct UpdatedItemsPage {
/// Latest snapshots of items changed within the requested interval.
pub items: Vec<StoredThreadItem>,
/// Opaque cursor to continue listing with the same timestamp bounds.
pub next_cursor: Option<String>,
/// Opaque cursor for fetching in the opposite direction with the same timestamp bounds.
pub backwards_cursor: Option<String>,
/// Store-confirmed inclusive upper bound. On success, this must match the requested upper
/// bound, including when that bound is absent.
pub read_through_updated_at: Option<DateTime<Utc>>,
}
/// Store-owned thread metadata used by list/read/resume responses.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct StoredThread {