codex: migrate (more) app-server thread history reads to ThreadStore (#20575)

Migrate token usage replay, rollback responses, and detached review
setup (a special case of forking) to be served from ThreadStore reads
rather direct rollout files.

- replay restored token usage from already-loaded `RolloutItem` history
instead of reopening `Thread.path`
- rebuild rollback responses from loaded `ThreadStore` snapshots and
history
- start detached reviews from store-backed parent history and stored
review-thread metadata
- remove obsolete app-server rollout-summary helper code that became
dead after the store-backed migration
- preserve response/notification ordering for resume, fork, rollback,
and detached review flows
- add integration test coverage for the affected paths
This commit is contained in:
Tom authored and GitHub committed 2026-05-04 21:16:50 -07:00
1 parent 7e71d02610
commit 33d24b0df5
11 files changed
+276 -147

No files matched your search

@@ -3006,23 +3006,10 @@ impl ThreadRequestProcessor {
// `excludeTurns` is the cheap fork path, so skip restored usage replay
// instead of rebuilding history only to attribute a historical update.
if let Some(token_usage_thread) = token_usage_thread {
let token_usage_turn_id = if let Some(rollout_path) = token_usage_thread.path.as_deref()
{
read_rollout_items_from_rollout(rollout_path)
.await
.ok()
.and_then(|rollout_items| {
latest_token_usage_turn_id_from_rollout_items(
&rollout_items,
token_usage_thread.turns.as_slice(),
)
})
} else {
latest_token_usage_turn_id_from_rollout_items(
&history_items,
token_usage_thread.turns.as_slice(),
)
};
let token_usage_turn_id = latest_token_usage_turn_id_from_rollout_items(
&history_items,
token_usage_thread.turns.as_slice(),
);
// Mirror the resume contract for forks: the new thread is usable as soon
// as the response arrives, so restored usage must follow immediately.
send_thread_token_usage_update_to_connection(
@@ -3588,7 +3575,7 @@ fn set_thread_name_from_title(thread: &mut Thread, title: String) {
thread.name = Some(title);
}
fn thread_from_stored_thread(
pub(crate) fn thread_from_stored_thread(
thread: StoredThread,
fallback_provider: &str,
fallback_cwd: &AbsolutePathBuf,