Create Insight Generation Feature

Added integration with Messages API and Ollama
This commit is contained in:
Cameron
2026-01-03 10:30:37 -05:00
parent 0dfec4c8c5
commit 1171f19845
18 changed files with 1365 additions and 34 deletions

View File

@@ -1,6 +1,9 @@
use crate::ai::{InsightGenerator, OllamaClient, SmsApiClient};
use crate::database::{ExifDao, InsightDao, SqliteExifDao, SqliteInsightDao};
use crate::video::actors::{PlaylistGenerator, StreamActor, VideoPlaylistManager};
use actix::{Actor, Addr};
use std::{env, sync::Arc};
use std::env;
use std::sync::{Arc, Mutex};
pub struct AppState {
pub stream_manager: Arc<Addr<StreamActor>>,
@@ -10,6 +13,10 @@ pub struct AppState {
pub video_path: String,
pub gif_path: String,
pub excluded_dirs: Vec<String>,
pub ollama: OllamaClient,
pub sms_client: SmsApiClient,
pub insight_generator: InsightGenerator,
pub insight_dao: Arc<Mutex<Box<dyn InsightDao>>>,
}
impl AppState {
@@ -20,6 +27,10 @@ impl AppState {
video_path: String,
gif_path: String,
excluded_dirs: Vec<String>,
ollama: OllamaClient,
sms_client: SmsApiClient,
insight_generator: InsightGenerator,
insight_dao: Arc<Mutex<Box<dyn InsightDao>>>,
) -> Self {
let playlist_generator = PlaylistGenerator::new();
let video_playlist_manager =
@@ -33,6 +44,10 @@ impl AppState {
video_path,
gif_path,
excluded_dirs,
ollama,
sms_client,
insight_generator,
insight_dao,
}
}
@@ -49,6 +64,31 @@ impl AppState {
impl Default for AppState {
fn default() -> Self {
// Initialize AI clients
let ollama_url =
env::var("OLLAMA_URL").unwrap_or_else(|_| "http://localhost:11434".to_string());
let ollama_model = env::var("OLLAMA_MODEL").unwrap_or_else(|_| "llama3.2".to_string());
let ollama = OllamaClient::new(ollama_url, ollama_model);
let sms_api_url =
env::var("SMS_API_URL").unwrap_or_else(|_| "http://localhost:8000".to_string());
let sms_api_token = env::var("SMS_API_TOKEN").ok();
let sms_client = SmsApiClient::new(sms_api_url, sms_api_token);
// Initialize DAOs
let insight_dao: Arc<Mutex<Box<dyn InsightDao>>> =
Arc::new(Mutex::new(Box::new(SqliteInsightDao::new())));
let exif_dao: Arc<Mutex<Box<dyn ExifDao>>> =
Arc::new(Mutex::new(Box::new(SqliteExifDao::new())));
// Initialize InsightGenerator
let insight_generator = InsightGenerator::new(
ollama.clone(),
sms_client.clone(),
insight_dao.clone(),
exif_dao.clone(),
);
Self::new(
Arc::new(StreamActor {}.start()),
env::var("BASE_PATH").expect("BASE_PATH was not set in the env"),
@@ -56,6 +96,10 @@ impl Default for AppState {
env::var("VIDEO_PATH").expect("VIDEO_PATH was not set in the env"),
env::var("GIFS_DIRECTORY").expect("GIFS_DIRECTORY was not set in the env"),
Self::parse_excluded_dirs(),
ollama,
sms_client,
insight_generator,
insight_dao,
)
}
}
@@ -74,14 +118,37 @@ impl AppState {
let video_path = create_test_subdir(&base_path, "videos");
let gif_path = create_test_subdir(&base_path, "gifs");
// Initialize test AI clients
let ollama =
OllamaClient::new("http://localhost:11434".to_string(), "llama3.2".to_string());
let sms_client = SmsApiClient::new("http://localhost:8000".to_string(), None);
// Initialize test DAOs
let insight_dao: Arc<Mutex<Box<dyn InsightDao>>> =
Arc::new(Mutex::new(Box::new(SqliteInsightDao::new())));
let exif_dao: Arc<Mutex<Box<dyn ExifDao>>> =
Arc::new(Mutex::new(Box::new(SqliteExifDao::new())));
// Initialize test InsightGenerator
let insight_generator = InsightGenerator::new(
ollama.clone(),
sms_client.clone(),
insight_dao.clone(),
exif_dao.clone(),
);
// Create the AppState with the temporary paths
AppState::new(
std::sync::Arc::new(crate::video::actors::StreamActor {}.start()),
Arc::new(StreamActor {}.start()),
base_path.to_string_lossy().to_string(),
thumbnail_path.to_string_lossy().to_string(),
video_path.to_string_lossy().to_string(),
gif_path.to_string_lossy().to_string(),
Vec::new(), // No excluded directories for test state
ollama,
sms_client,
insight_generator,
insight_dao,
)
}
}