remem-ai 0.5.209

Local-first coding agent memory for Claude Code and OpenAI Codex
Documentation
use std::borrow::Cow;

use anyhow::Result;
use rusqlite::{params, Connection};

use super::sql::{column_exists, table_exists};
use super::{FailureSurfaceStats, MAX_FAILURE_AUTO_RETRIES, SECONDS_PER_DAY};

#[derive(Debug, Clone)]
pub(super) struct SurfaceQuery {
    pub(super) surface: &'static str,
    pub(super) table: &'static str,
    pub(super) failed_predicate: Cow<'static, str>,
    pub(super) attempt_column: &'static str,
    pub(super) created_column: &'static str,
    pub(super) updated_column: &'static str,
}

pub(super) fn query_surface_stats(
    conn: &Connection,
    query: SurfaceQuery,
    now_epoch: i64,
) -> Result<FailureSurfaceStats> {
    if !table_exists(conn, query.table)? {
        return Ok(FailureSurfaceStats::default());
    }
    let has_lifecycle = column_exists(conn, query.table, "archived_at_epoch")?;
    let attempt_expr = if column_exists(conn, query.table, query.attempt_column)? {
        query.attempt_column
    } else {
        "0"
    };
    let updated_expr = if column_exists(conn, query.table, query.updated_column)? {
        query.updated_column
    } else {
        "0"
    };
    let created_expr = if column_exists(conn, query.table, query.created_column)? {
        query.created_column
    } else {
        "0"
    };
    let class_expr = if has_lifecycle {
        "COALESCE(failure_class, 'transient')".to_string()
    } else {
        "'transient'".to_string()
    };
    let failed_at_expr = if has_lifecycle {
        format!(
            "COALESCE(failed_at_epoch, NULLIF({updated}, 0), {created})",
            updated = updated_expr,
            created = created_expr
        )
    } else {
        format!(
            "COALESCE(NULLIF({updated}, 0), {created})",
            updated = updated_expr,
            created = created_expr
        )
    };
    let archived_filter = if has_lifecycle {
        "archived_at_epoch IS NULL"
    } else {
        "1 = 1"
    };
    let week_ago = now_epoch.saturating_sub(7 * SECONDS_PER_DAY);
    let sql = format!(
        "SELECT
            COUNT(*) AS actionable_total,
            COALESCE(SUM(CASE WHEN {failed_at_expr} >= ?1 THEN 1 ELSE 0 END), 0) AS actionable_7d,
            COALESCE(SUM(CASE WHEN {class_expr} = 'transient' THEN 1 ELSE 0 END), 0) AS transient,
            COALESCE(SUM(CASE WHEN {class_expr} = 'permanent' THEN 1 ELSE 0 END), 0) AS permanent,
            COALESCE(SUM(CASE WHEN {attempt_col} >= ?2 THEN 1 ELSE 0 END), 0) AS exhausted,
            MIN({failed_at_expr}) AS oldest_actionable_epoch
         FROM {table}
         WHERE {failed_predicate}
           AND {archived_filter}",
        attempt_col = attempt_expr,
        table = query.table,
        failed_predicate = query.failed_predicate
    );
    let (actionable_total, actionable_7d, transient, permanent, exhausted, oldest): (
        i64,
        i64,
        i64,
        i64,
        i64,
        Option<i64>,
    ) = conn.query_row(&sql, params![week_ago, MAX_FAILURE_AUTO_RETRIES], |row| {
        Ok((
            row.get(0)?,
            row.get(1)?,
            row.get(2)?,
            row.get(3)?,
            row.get(4)?,
            row.get(5)?,
        ))
    })?;
    let archived = if has_lifecycle {
        let sql = format!(
            "SELECT COUNT(*) FROM {table}
             WHERE {failed_predicate} AND archived_at_epoch IS NOT NULL",
            table = query.table,
            failed_predicate = query.failed_predicate
        );
        conn.query_row(&sql, [], |row| row.get(0))?
    } else {
        0
    };
    let (historical_archived, historical_purged) = query_historical_counts(conn, query.surface)?;
    Ok(FailureSurfaceStats {
        actionable_total,
        actionable_7d,
        transient,
        permanent,
        exhausted,
        archived,
        historical_archived,
        historical_purged,
        oldest_actionable_epoch: oldest,
    })
}

fn query_historical_counts(conn: &Connection, surface: &str) -> Result<(i64, i64)> {
    if !table_exists(conn, "failure_lifecycle_daily")? {
        return Ok((0, 0));
    }
    conn.query_row(
        "SELECT COALESCE(SUM(archived_count), 0), COALESCE(SUM(purged_count), 0)
         FROM failure_lifecycle_daily
         WHERE surface = ?1",
        [surface],
        |row| Ok((row.get(0)?, row.get(1)?)),
    )
    .map_err(Into::into)
}