Add occurrence search for paginated threads (#33907)

## What changed

- Add the experimental `thread/searchOccurrences` app-server method for case-insensitive literal search across visible user messages and final assistant messages without replaying the thread.
- Return paginated snippets with UTF-16 match ranges and `thread/turns/list` cursors for navigating to each matching turn.
- Index persisted item types to efficiently select searchable messages from paginated thread history.

## Testing

- Add an app-server integration test covering pagination, steering messages, final-answer selection, Markdown normalization, and UTF-16 offsets.

GitOrigin-RevId: e80160e0f83eb4e5db8de862307085093bee362b
This commit is contained in:
Owen Lin authored and copyberry committed 2026-07-17 21:24:26 +00:00
1 parent 9f6c29e281
commit c1862b8db4
21 files changed
+875 -23

No files matched your search

+17
View File
@@ -39,10 +39,12 @@ use crate::LoadThreadHistoryParams;
use crate::ReadThreadByRolloutPathParams;
use crate::ReadThreadParams;
use crate::ResumeThreadParams;
use crate::SearchThreadOccurrencesParams;
use crate::SearchThreadsParams;
use crate::StoredModelContext;
use crate::StoredThread;
use crate::StoredThreadHistory;
use crate::ThreadOccurrenceSearchPage;
use crate::ThreadPage;
use crate::ThreadSearchPage;
use crate::ThreadStore;
@@ -278,6 +280,14 @@ impl LocalThreadStore {
pub async fn list_items(&self, params: ListItemsParams) -> ThreadStoreResult<ItemPage> {
thread_history::list_items(self, params).await
}
/// Searches projection-backed visible messages within one paginated thread.
pub async fn search_thread_occurrences(
&self,
params: SearchThreadOccurrencesParams,
) -> ThreadStoreResult<ThreadOccurrenceSearchPage> {
thread_history::search_thread_occurrences(self, params).await
}
}
impl ThreadStore for LocalThreadStore {
@@ -363,6 +373,13 @@ impl ThreadStore for LocalThreadStore {
Box::pin(async move { search_threads::search_threads(self, params).await })
}
fn search_thread_occurrences(
&self,
params: SearchThreadOccurrencesParams,
) -> ThreadStoreFuture<'_, ThreadOccurrenceSearchPage> {
Box::pin(LocalThreadStore::search_thread_occurrences(self, params))
}
fn update_thread_metadata(
&self,
params: UpdateThreadMetadataParams,