Load model context from a bounded rollout suffix (#32896)

## Why

Reconstructing the latest model-visible context does not require replaying an
entire paginated rollout when a usable compaction checkpoint and the associated
completed-turn metadata are available.

## What changed

- Add `ThreadStore::load_latest_model_context` and `StoredModelContext` for
  loading replay-ready model context independently of full thread history.
- Reverse-scan plain paginated JSONL rollouts until the newest safe bounded
  suffix is found, while preserving canonical session metadata and chronological
  replay order.
- Fall back to complete history for legacy or compressed rollouts and whenever
  compaction or rollback records make a bounded cutoff unsafe.

## Testing

- Cover checkpoint selection, turn-metadata boundaries, agent messages,
  contextual user fragments, and full-history fallbacks.

GitOrigin-RevId: 3572f4ecc7aa4099a6d9f0d3e72d0ef432cd9497
This commit is contained in:
Owen Lin authored and copyberry committed 2026-07-13 23:29:59 +00:00
1 parent 7fdf2f254b
commit 592467fb96
13 files changed
+812 -17

No files matched your search

+15
View File
@@ -17,6 +17,7 @@ use crate::ReadThreadByRolloutPathParams;
use crate::ReadThreadParams;
use crate::ResumeThreadParams;
use crate::SearchThreadsParams;
use crate::StoredModelContext;
use crate::StoredThread;
use crate::StoredThreadHistory;
use crate::ThreadPage;
@@ -76,6 +77,20 @@ pub trait ThreadStore: Any + Send + Sync {
params: LoadThreadHistoryParams,
) -> ThreadStoreFuture<'_, StoredThreadHistory>;
/// Loads the persisted rollout items needed to reconstruct the latest model-visible context.
///
/// Implementations that cannot perform a targeted read may return the full persisted history.
fn load_latest_model_context(
&self,
_params: LoadThreadHistoryParams,
) -> ThreadStoreFuture<'_, StoredModelContext> {
Box::pin(async {
Err(ThreadStoreError::Unsupported {
operation: "load_latest_model_context",
})
})
}
/// Reads a thread summary and optionally its persisted history.
fn read_thread(&self, params: ReadThreadParams) -> ThreadStoreFuture<'_, StoredThread>;