Enable memories for paginated threads (#34386)

## Why

Paginated threads keep metadata updates in SQLite, while their rollout retains the initial `memory_mode`. Reconciliation could therefore overwrite the current setting with a stale value, and memory processing excluded these threads entirely.

## What changed

- Include paginated threads in stage 1 memory job selection and global memory output lookup.
- Preserve the SQLite `memory_mode` when reconciling or backfilling an existing paginated thread, while continuing to seed missing rows and restore legacy threads from rollouts.
- Omit `memory_mode` alongside Git metadata when flushing resumed paginated history.

## Testing

Added coverage for preserving disabled memory mode during reconciliation and backfill, selecting eligible paginated threads, and omitting initial metadata on paginated resume.

GitOrigin-RevId: 2a6e16068e69680728757fbec27aeefae45b8110
This commit is contained in:
Owen Lin authored and copyberry committed 2026-07-20 17:41:33 +00:00
1 parent 6f785632b0
commit 2793c826e8
6 files changed
+154 -29

No files matched your search

+13 -6
View File
@@ -11,6 +11,7 @@ use chrono::Utc;
use codex_protocol::ThreadId;
use codex_protocol::protocol::RolloutItem;
use codex_protocol::protocol::SessionSource;
use codex_protocol::protocol::ThreadHistoryMode;
pub use codex_state::LogEntry;
use codex_state::ThreadMetadataBuilder;
use codex_utils_path::normalize_for_path_comparison;
@@ -528,9 +529,14 @@ pub async fn reconcile_rollout(
let mut metadata = outcome.metadata;
let memory_mode = outcome.memory_mode.unwrap_or_else(|| "enabled".to_string());
metadata.cwd = normalize_cwd_for_state_db(&metadata.cwd);
if let Ok(Some(existing_metadata)) = ctx.get_thread(metadata.id).await {
metadata.prefer_existing_git_info(&existing_metadata);
metadata.prefer_existing_explicit_title(&existing_metadata);
let existing_metadata = ctx.get_thread(metadata.id).await.ok().flatten();
// Paginated metadata updates are SQLite-only. Use the rollout mode to seed a
// missing row, then keep the value from SQLite.
let restore_memory_mode_from_rollout =
existing_metadata.is_none() || matches!(metadata.history_mode, ThreadHistoryMode::Legacy);
if let Some(existing_metadata) = existing_metadata.as_ref() {
metadata.prefer_existing_git_info(existing_metadata);
metadata.prefer_existing_explicit_title(existing_metadata);
}
match archived_only {
Some(true) if metadata.archived_at.is_none() => {
@@ -548,9 +554,10 @@ pub async fn reconcile_rollout(
);
return;
}
if let Err(err) = ctx
.set_thread_memory_mode(metadata.id, memory_mode.as_str())
.await
if restore_memory_mode_from_rollout
&& let Err(err) = ctx
.set_thread_memory_mode(metadata.id, memory_mode.as_str())
.await
{
warn!(
"state db reconcile_rollout memory_mode update failed {}: {err}",