feat: add phase 1 mem db (#10634)

- Schema: thread_id (PK, FK to threads.id with cascade delete),
trace_summary, memory_summary, updated_at.
- Migration: creates the table and an index on (updated_at DESC,
thread_id DESC) for efficient recent-first reads.
  - Runtime API (DB-only):
      - `get_thread_memory(thread_id)`: fetch one memory row.
- `upsert_thread_memory(thread_id, trace_summary, memory_summary)`:
insert/update by thread id and always advance updated_at.
- `get_last_n_thread_memories_for_cwd(cwd, n)`: join thread_memory with
threads and return newest n rows for an exact cwd match.
- Model layer: introduced ThreadMemory and row conversion types to keep
query decoding typed and consistent with existing state models.
This commit is contained in:
jif-oai
2026-02-04 21:38:39 +00:00
committed by GitHub
Unverified
parent 7a253076fe
commit 4922b3e571
6 changed files with 517 additions and 0 deletions
+54
View File
@@ -280,6 +280,60 @@ pub async fn persist_dynamic_tools(
}
}
/// Get memory summaries for a thread id using SQLite.
pub async fn get_thread_memory(
context: Option<&codex_state::StateRuntime>,
thread_id: ThreadId,
stage: &str,
) -> Option<codex_state::ThreadMemory> {
let ctx = context?;
match ctx.get_thread_memory(thread_id).await {
Ok(memory) => memory,
Err(err) => {
warn!("state db get_thread_memory failed during {stage}: {err}");
None
}
}
}
/// Upsert memory summaries for a thread id using SQLite.
pub async fn upsert_thread_memory(
context: Option<&codex_state::StateRuntime>,
thread_id: ThreadId,
trace_summary: &str,
memory_summary: &str,
stage: &str,
) -> Option<codex_state::ThreadMemory> {
let ctx = context?;
match ctx
.upsert_thread_memory(thread_id, trace_summary, memory_summary)
.await
{
Ok(memory) => Some(memory),
Err(err) => {
warn!("state db upsert_thread_memory failed during {stage}: {err}");
None
}
}
}
/// Get the last N memories corresponding to a cwd using an exact path match.
pub async fn get_last_n_thread_memories_for_cwd(
context: Option<&codex_state::StateRuntime>,
cwd: &Path,
n: usize,
stage: &str,
) -> Option<Vec<codex_state::ThreadMemory>> {
let ctx = context?;
match ctx.get_last_n_thread_memories_for_cwd(cwd, n).await {
Ok(memories) => Some(memories),
Err(err) => {
warn!("state db get_last_n_thread_memories_for_cwd failed during {stage}: {err}");
None
}
}
}
/// Reconcile rollout items into SQLite, falling back to scanning the rollout file.
pub async fn reconcile_rollout(
context: Option<&codex_state::StateRuntime>,