Cargo fix

This commit is contained in:
Cameron
2026-01-05 10:24:12 -05:00
parent ad07f5a1fa
commit bb23e6bb25
12 changed files with 204 additions and 122 deletions

View File

@@ -1,7 +1,7 @@
use anyhow::Result;
use chrono::{DateTime, Utc};
use opentelemetry::trace::{Span, Status, TraceContextExt, Tracer};
use opentelemetry::KeyValue;
use opentelemetry::trace::{Span, Status, TraceContextExt, Tracer};
use serde::Deserialize;
use std::fs::File;
use std::sync::{Arc, Mutex};
@@ -89,19 +89,31 @@ impl InsightGenerator {
limit: usize,
) -> Result<Vec<String>> {
let tracer = global_tracer();
let mut span = tracer.start_with_context("ai.rag.filter_historical", parent_cx);
let span = tracer.start_with_context("ai.rag.filter_historical", parent_cx);
let filter_cx = parent_cx.with_span(span);
filter_cx.span().set_attribute(KeyValue::new("date", date.to_string()));
filter_cx.span().set_attribute(KeyValue::new("limit", limit as i64));
filter_cx.span().set_attribute(KeyValue::new("exclusion_window_days", 30));
filter_cx
.span()
.set_attribute(KeyValue::new("date", date.to_string()));
filter_cx
.span()
.set_attribute(KeyValue::new("limit", limit as i64));
filter_cx
.span()
.set_attribute(KeyValue::new("exclusion_window_days", 30));
let query_results = self.find_relevant_messages_rag(date, location, contact, limit * 2).await?;
let query_results = self
.find_relevant_messages_rag(date, location, contact, limit * 2)
.await?;
filter_cx.span().set_attribute(KeyValue::new("rag_results_count", query_results.len() as i64));
filter_cx.span().set_attribute(KeyValue::new(
"rag_results_count",
query_results.len() as i64,
));
// Filter out messages from within 30 days of the photo date
let photo_timestamp = date.and_hms_opt(12, 0, 0)
let photo_timestamp = date
.and_hms_opt(12, 0, 0)
.ok_or_else(|| anyhow::anyhow!("Invalid date"))?
.and_utc()
.timestamp();
@@ -114,7 +126,9 @@ impl InsightGenerator {
if let Some(bracket_end) = msg.find(']') {
if let Some(date_str) = msg.get(1..bracket_end) {
// Parse just the date (daily summaries don't have time)
if let Ok(msg_date) = chrono::NaiveDate::parse_from_str(date_str, "%Y-%m-%d") {
if let Ok(msg_date) =
chrono::NaiveDate::parse_from_str(date_str, "%Y-%m-%d")
{
let msg_timestamp = msg_date
.and_hms_opt(12, 0, 0)
.unwrap()
@@ -135,7 +149,10 @@ impl InsightGenerator {
historical_only.len()
);
filter_cx.span().set_attribute(KeyValue::new("historical_results_count", historical_only.len() as i64));
filter_cx.span().set_attribute(KeyValue::new(
"historical_results_count",
historical_only.len() as i64,
));
filter_cx.span().set_status(Status::Ok);
Ok(historical_only)
@@ -206,9 +223,15 @@ impl InsightGenerator {
.find_similar_summaries(&search_cx, &query_embedding, limit)
.map_err(|e| anyhow::anyhow!("Failed to find similar summaries: {:?}", e))?;
log::info!("Found {} relevant daily summaries via RAG", similar_summaries.len());
log::info!(
"Found {} relevant daily summaries via RAG",
similar_summaries.len()
);
search_cx.span().set_attribute(KeyValue::new("results_count", similar_summaries.len() as i64));
search_cx.span().set_attribute(KeyValue::new(
"results_count",
similar_summaries.len() as i64,
));
// Format daily summaries for LLM context
let formatted = similar_summaries
@@ -303,9 +326,13 @@ impl InsightGenerator {
let contact = Self::extract_contact_from_path(&file_path);
log::info!("Extracted contact from path: {:?}", contact);
insight_cx.span().set_attribute(KeyValue::new("date_taken", date_taken.to_string()));
insight_cx
.span()
.set_attribute(KeyValue::new("date_taken", date_taken.to_string()));
if let Some(ref c) = contact {
insight_cx.span().set_attribute(KeyValue::new("contact", c.clone()));
insight_cx
.span()
.set_attribute(KeyValue::new("contact", c.clone()));
}
// 4. Get location name from GPS coordinates (needed for RAG query)
@@ -314,7 +341,9 @@ impl InsightGenerator {
if let (Some(lat), Some(lon)) = (exif.gps_latitude, exif.gps_longitude) {
let loc = self.reverse_geocode(lat, lon).await;
if let Some(ref l) = loc {
insight_cx.span().set_attribute(KeyValue::new("location", l.clone()));
insight_cx
.span()
.set_attribute(KeyValue::new("location", l.clone()));
}
loc
} else {
@@ -341,12 +370,7 @@ impl InsightGenerator {
// Strategy A: Pure RAG (we have location for good semantic matching)
log::info!("Using RAG with location-based query");
match self
.find_relevant_messages_rag(
date_taken,
location.as_deref(),
contact.as_deref(),
20,
)
.find_relevant_messages_rag(date_taken, location.as_deref(), contact.as_deref(), 20)
.await
{
Ok(rag_messages) if !rag_messages.is_empty() => {
@@ -377,7 +401,9 @@ impl InsightGenerator {
if !immediate_messages.is_empty() {
// Step 2: Extract topics from immediate messages to enrich RAG query
let topics = self.extract_topics_from_messages(&immediate_messages, &ollama_client).await;
let topics = self
.extract_topics_from_messages(&immediate_messages, &ollama_client)
.await;
log::info!("Extracted topics for query enrichment: {:?}", topics);
@@ -420,11 +446,15 @@ impl InsightGenerator {
Ok(_) => {
// RAG found no historical matches, just use immediate context
log::info!("No historical RAG matches, using immediate context only");
sms_summary = self.summarize_context_from_messages(&immediate_messages, &ollama_client).await;
sms_summary = self
.summarize_context_from_messages(&immediate_messages, &ollama_client)
.await;
}
Err(e) => {
log::warn!("Historical RAG failed, using immediate context only: {}", e);
sms_summary = self.summarize_context_from_messages(&immediate_messages, &ollama_client).await;
sms_summary = self
.summarize_context_from_messages(&immediate_messages, &ollama_client)
.await;
}
}
} else {
@@ -481,8 +511,12 @@ impl InsightGenerator {
}
let retrieval_method = if used_rag { "RAG" } else { "time-based" };
insight_cx.span().set_attribute(KeyValue::new("retrieval_method", retrieval_method));
insight_cx.span().set_attribute(KeyValue::new("has_sms_context", sms_summary.is_some()));
insight_cx
.span()
.set_attribute(KeyValue::new("retrieval_method", retrieval_method));
insight_cx
.span()
.set_attribute(KeyValue::new("has_sms_context", sms_summary.is_some()));
log::info!(
"Photo context: date={}, location={:?}, retrieval_method={}",
@@ -503,8 +537,12 @@ impl InsightGenerator {
log::info!("Generated title: {}", title);
log::info!("Generated summary: {}", summary);
insight_cx.span().set_attribute(KeyValue::new("title_length", title.len() as i64));
insight_cx.span().set_attribute(KeyValue::new("summary_length", summary.len() as i64));
insight_cx
.span()
.set_attribute(KeyValue::new("title_length", title.len() as i64));
insight_cx
.span()
.set_attribute(KeyValue::new("summary_length", summary.len() as i64));
// 8. Store in database
let insight = InsertPhotoInsight {
@@ -516,7 +554,8 @@ impl InsightGenerator {
};
let mut dao = self.insight_dao.lock().expect("Unable to lock InsightDao");
let result = dao.store_insight(&insight_cx, insight)
let result = dao
.store_insight(&insight_cx, insight)
.map_err(|e| anyhow::anyhow!("Failed to store insight: {:?}", e));
match &result {