feat(core): add ollama lifecycle management for cron sync
Add src/core/ollama_mgmt.rs module that handles Ollama detection, startup, and health checking. This enables cron-based sync to automatically start Ollama when it's installed but not running, ensuring embeddings are always available during unattended sync runs. Integration points: - sync handler (--lock mode): calls ensure_ollama() before embedding phase - cron status: displays Ollama health (installed/running/not-installed) - robot JSON: includes OllamaStatusBrief in cron status response The module handles local vs remote Ollama URLs, IPv6, process detection via lsof, and graceful startup with configurable wait timeouts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ use crate::core::cron::{
|
||||
};
|
||||
use crate::core::db::create_connection;
|
||||
use crate::core::error::Result;
|
||||
use crate::core::ollama_mgmt::{OllamaStatusBrief, ollama_status_brief};
|
||||
use crate::core::paths::get_db_path;
|
||||
use crate::core::time::ms_to_iso;
|
||||
|
||||
@@ -143,12 +144,20 @@ pub fn run_cron_status(config: &Config) -> Result<CronStatusInfo> {
|
||||
// Query last sync run from DB
|
||||
let last_sync = get_last_sync_time(config).unwrap_or_default();
|
||||
|
||||
Ok(CronStatusInfo { status, last_sync })
|
||||
// Quick ollama health check
|
||||
let ollama = ollama_status_brief(&config.embedding.base_url);
|
||||
|
||||
Ok(CronStatusInfo {
|
||||
status,
|
||||
last_sync,
|
||||
ollama,
|
||||
})
|
||||
}
|
||||
|
||||
pub struct CronStatusInfo {
|
||||
pub status: CronStatusResult,
|
||||
pub last_sync: Option<LastSyncInfo>,
|
||||
pub ollama: OllamaStatusBrief,
|
||||
}
|
||||
|
||||
pub struct LastSyncInfo {
|
||||
@@ -236,6 +245,32 @@ pub fn print_cron_status(info: &CronStatusInfo) {
|
||||
last.status
|
||||
);
|
||||
}
|
||||
|
||||
// Ollama status
|
||||
if info.ollama.installed {
|
||||
if info.ollama.running {
|
||||
println!(
|
||||
" {} running (auto-started by cron if needed)",
|
||||
Theme::dim().render("ollama:")
|
||||
);
|
||||
} else {
|
||||
println!(
|
||||
" {} {}",
|
||||
Theme::warning().render("ollama:"),
|
||||
Theme::warning()
|
||||
.render("installed but not running (will attempt start on next sync)")
|
||||
);
|
||||
}
|
||||
} else {
|
||||
println!(
|
||||
" {} {}",
|
||||
Theme::error().render("ollama:"),
|
||||
Theme::error().render("not installed — embeddings unavailable")
|
||||
);
|
||||
if let Some(ref hint) = info.ollama.install_hint {
|
||||
println!(" {hint}");
|
||||
}
|
||||
}
|
||||
println!();
|
||||
}
|
||||
|
||||
@@ -264,6 +299,7 @@ struct CronStatusData {
|
||||
last_sync_at: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
last_sync_status: Option<String>,
|
||||
ollama: OllamaStatusBrief,
|
||||
}
|
||||
|
||||
pub fn print_cron_status_json(info: &CronStatusInfo, elapsed_ms: u64) {
|
||||
@@ -283,6 +319,7 @@ pub fn print_cron_status_json(info: &CronStatusInfo, elapsed_ms: u64) {
|
||||
cron_entry: info.status.cron_entry.clone(),
|
||||
last_sync_at: info.last_sync.as_ref().map(|s| s.started_at_iso.clone()),
|
||||
last_sync_status: info.last_sync.as_ref().map(|s| s.status.clone()),
|
||||
ollama: info.ollama.clone(),
|
||||
},
|
||||
meta: RobotMeta::new(elapsed_ms),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user