remem-ai 0.6.81

Local-first coding agent memory for Claude Code and OpenAI Codex
Documentation
use anyhow::Result;
use serde::Serialize;

use crate::cli::embedding_types::EmbeddingAction;

pub(in crate::cli) fn run_embedding(action: EmbeddingAction) -> Result<()> {
    match action {
        EmbeddingAction::Download { model, json } => {
            let report =
                crate::retrieval::embedding::download_local_embedding_model(model.as_deref())?;
            if json {
                println!("{}", serde_json::to_string_pretty(&report)?);
            } else {
                println!(
                    "Downloaded local embedding model {} ({}, {} dims) into {}.",
                    report.model_id, report.upstream_model, report.dimensions, report.install_dir
                );
                println!("Verified {} model files.", report.files_verified);
            }
            Ok(())
        }
        EmbeddingAction::Status { json } => run_embedding_status(json),
        EmbeddingAction::Backfill {
            batch,
            limit,
            prune,
            json,
        } => {
            super::query::run_embedding_backfill(limit, batch, prune, json)?;
            Ok(())
        }
    }
}

fn run_embedding_status(json: bool) -> Result<()> {
    let provider = crate::retrieval::embedding::embedding_provider_status()?;
    let inventory = crate::retrieval::embedding::local_embedding_inventory()?;
    let report = EmbeddingStatusCliReport {
        configured_provider: provider.configured_provider,
        fallback_provider: provider.fallback_provider,
        active_provider: provider.active_provider,
        active_model_id: provider.active_model_id,
        active_dimensions: provider.active_dimensions,
        degraded: provider.degraded,
        disabled: provider.disabled,
        unavailable_reason: provider.unavailable_reason,
        degradation_reason: provider.degradation_reason,
        model_root: inventory.model_root,
        configured_preset: inventory.configured_preset,
        models: inventory.models,
    };
    if json {
        println!("{}", serde_json::to_string_pretty(&report)?);
    } else {
        println!(
            "Embedding provider: {} -> {}",
            report.configured_provider, report.active_provider
        );
        if let Some(fallback) = &report.fallback_provider {
            println!("Fallback: {}", fallback);
        }
        println!(
            "Active model: {}",
            report.active_model_id.as_deref().unwrap_or("none")
        );
        println!(
            "State: degraded={} disabled={}",
            report.degraded, report.disabled
        );
        if let Some(reason) = &report.unavailable_reason {
            println!("Unavailable: {}", reason);
        } else if let Some(reason) = &report.degradation_reason {
            println!("Degraded: {}", reason);
        }
        println!("Model root: {}", report.model_root);
        println!("Configured preset: {}", report.configured_preset);
        for model in &report.models {
            let state = if model.installed {
                "installed"
            } else {
                "missing"
            };
            println!(
                "  {}: {} ({} dims) {}",
                model.preset, model.model_id, model.dimensions, state
            );
            if let Some(reason) = &model.unavailable_reason {
                println!("    {}", reason);
            }
        }
    }
    Ok(())
}

#[derive(Debug, Clone, PartialEq, Serialize)]
struct EmbeddingStatusCliReport {
    configured_provider: String,
    fallback_provider: Option<String>,
    active_provider: String,
    active_model_id: Option<String>,
    active_dimensions: Option<usize>,
    degraded: bool,
    disabled: bool,
    unavailable_reason: Option<String>,
    degradation_reason: Option<String>,
    model_root: String,
    configured_preset: String,
    models: Vec<crate::retrieval::embedding::LocalEmbeddingModelInventory>,
}