feature/insight-jobs #102

Merged
cameron merged 13 commits from feature/insight-jobs into master 2026-06-02 23:41:37 +00:00
6 changed files with 31 additions and 9 deletions
Showing only changes of commit 9654d256f4 - Show all commits
@@ -1,4 +1,4 @@
-- Persist generation parameters on each insight row for auditing. -- Persist generation parameters and token usage on each insight row.
ALTER TABLE photo_insights ADD COLUMN num_ctx INTEGER; ALTER TABLE photo_insights ADD COLUMN num_ctx INTEGER;
ALTER TABLE photo_insights ADD COLUMN temperature REAL; ALTER TABLE photo_insights ADD COLUMN temperature REAL;
ALTER TABLE photo_insights ADD COLUMN top_p REAL; ALTER TABLE photo_insights ADD COLUMN top_p REAL;
@@ -6,3 +6,5 @@ ALTER TABLE photo_insights ADD COLUMN top_k INTEGER;
ALTER TABLE photo_insights ADD COLUMN min_p REAL; ALTER TABLE photo_insights ADD COLUMN min_p REAL;
ALTER TABLE photo_insights ADD COLUMN system_prompt TEXT; ALTER TABLE photo_insights ADD COLUMN system_prompt TEXT;
ALTER TABLE photo_insights ADD COLUMN persona_id TEXT; ALTER TABLE photo_insights ADD COLUMN persona_id TEXT;
ALTER TABLE photo_insights ADD COLUMN prompt_eval_count INTEGER;
ALTER TABLE photo_insights ADD COLUMN eval_count INTEGER;
+6 -6
View File
@@ -561,8 +561,8 @@ pub async fn get_insight_handler(
summary: insight.summary, summary: insight.summary,
generated_at: insight.generated_at, generated_at: insight.generated_at,
model_version: insight.model_version, model_version: insight.model_version,
prompt_eval_count: None, prompt_eval_count: insight.prompt_eval_count,
eval_count: None, eval_count: insight.eval_count,
approved: insight.approved, approved: insight.approved,
has_training_messages: insight.training_messages.is_some(), has_training_messages: insight.training_messages.is_some(),
backend: insight.backend, backend: insight.backend,
@@ -637,8 +637,8 @@ pub async fn get_all_insights_handler(
summary: insight.summary, summary: insight.summary,
generated_at: insight.generated_at, generated_at: insight.generated_at,
model_version: insight.model_version, model_version: insight.model_version,
prompt_eval_count: None, prompt_eval_count: insight.prompt_eval_count,
eval_count: None, eval_count: insight.eval_count,
approved: insight.approved, approved: insight.approved,
has_training_messages: insight.training_messages.is_some(), has_training_messages: insight.training_messages.is_some(),
backend: insight.backend, backend: insight.backend,
@@ -833,12 +833,12 @@ pub async fn generate_agentic_insight_handler(
let mut dao = job_dao.lock().expect("Unable to lock InsightJobDao"); let mut dao = job_dao.lock().expect("Unable to lock InsightJobDao");
match result { match result {
Ok(Ok(Ok((Some(insight_id), _)))) => { Ok(Ok(Ok((Some(insight_id), _, _)))) => {
if let Err(e) = dao.complete_job(&ctx, job_id, insight_id) { if let Err(e) = dao.complete_job(&ctx, job_id, insight_id) {
log::error!("Failed to mark job {} as completed: {:?}", job_id, e); log::error!("Failed to mark job {} as completed: {:?}", job_id, e);
} }
} }
Ok(Ok(Ok((None, _)))) => { Ok(Ok(Ok((None, _, _)))) => {
if let Err(e) = dao.fail_job(&ctx, job_id, "agentic generation returned no insight") if let Err(e) = dao.fail_job(&ctx, job_id, "agentic generation returned no insight")
{ {
log::error!("Failed to mark job {} as failed: {:?}", job_id, e); log::error!("Failed to mark job {} as failed: {:?}", job_id, e);
+6
View File
@@ -524,6 +524,8 @@ impl InsightChatService {
min_p: req.min_p, min_p: req.min_p,
system_prompt: req.system_prompt.clone(), system_prompt: req.system_prompt.clone(),
persona_id: req.persona_id.clone(), persona_id: req.persona_id.clone(),
prompt_eval_count: None,
eval_count: None,
}; };
let cx = opentelemetry::Context::new(); let cx = opentelemetry::Context::new();
let mut dao = self.insight_dao.lock().expect("Unable to lock InsightDao"); let mut dao = self.insight_dao.lock().expect("Unable to lock InsightDao");
@@ -878,6 +880,8 @@ impl InsightChatService {
min_p: req.min_p, min_p: req.min_p,
system_prompt: req.system_prompt.clone(), system_prompt: req.system_prompt.clone(),
persona_id: req.persona_id.clone(), persona_id: req.persona_id.clone(),
prompt_eval_count: None,
eval_count: None,
}; };
let cx = opentelemetry::Context::new(); let cx = opentelemetry::Context::new();
let mut dao = self.insight_dao.lock().expect("Unable to lock InsightDao"); let mut dao = self.insight_dao.lock().expect("Unable to lock InsightDao");
@@ -1073,6 +1077,8 @@ impl InsightChatService {
min_p: req.min_p, min_p: req.min_p,
system_prompt: req.system_prompt.clone(), system_prompt: req.system_prompt.clone(),
persona_id: req.persona_id.clone(), persona_id: req.persona_id.clone(),
prompt_eval_count: None,
eval_count: None,
}; };
let stored = { let stored = {
let cx = opentelemetry::Context::new(); let cx = opentelemetry::Context::new();
+10 -2
View File
@@ -1439,6 +1439,8 @@ impl InsightGenerator {
min_p, min_p,
system_prompt: custom_system_prompt.clone(), system_prompt: custom_system_prompt.clone(),
persona_id: None, persona_id: None,
prompt_eval_count: None,
eval_count: None,
}; };
let mut dao = self.insight_dao.lock().expect("Unable to lock InsightDao"); let mut dao = self.insight_dao.lock().expect("Unable to lock InsightDao");
@@ -3808,7 +3810,7 @@ Return ONLY the summary, nothing else."#,
fewshot_source_ids: Vec<i32>, fewshot_source_ids: Vec<i32>,
user_id: i32, user_id: i32,
persona_id: String, persona_id: String,
) -> Result<(Option<i32>, Option<i32>)> { ) -> Result<(Option<i32>, Option<i32>, Option<i32>)> {
let tracer = global_tracer(); let tracer = global_tracer();
let current_cx = opentelemetry::Context::current(); let current_cx = opentelemetry::Context::current();
let mut span = tracer.start_with_context("ai.insight.generate_agentic", &current_cx); let mut span = tracer.start_with_context("ai.insight.generate_agentic", &current_cx);
@@ -4190,6 +4192,8 @@ Return ONLY the summary, nothing else."#,
min_p, min_p,
system_prompt: custom_system_prompt.clone(), system_prompt: custom_system_prompt.clone(),
persona_id: Some(persona_id.clone()), persona_id: Some(persona_id.clone()),
prompt_eval_count: last_prompt_eval_count,
eval_count: last_eval_count,
}; };
let stored = { let stored = {
@@ -4227,7 +4231,11 @@ Return ONLY the summary, nothing else."#,
} }
} }
Ok((last_prompt_eval_count, last_eval_count)) Ok((
Some(stored_insight.id),
last_prompt_eval_count,
last_eval_count,
))
} }
/// Reverse geocode GPS coordinates to human-readable place names /// Reverse geocode GPS coordinates to human-readable place names
+4
View File
@@ -225,6 +225,8 @@ pub struct InsertPhotoInsight {
pub min_p: Option<f32>, pub min_p: Option<f32>,
pub system_prompt: Option<String>, pub system_prompt: Option<String>,
pub persona_id: Option<String>, pub persona_id: Option<String>,
pub prompt_eval_count: Option<i32>,
pub eval_count: Option<i32>,
} }
#[derive(Serialize, Queryable, Clone, Debug)] #[derive(Serialize, Queryable, Clone, Debug)]
@@ -251,6 +253,8 @@ pub struct PhotoInsight {
pub min_p: Option<f32>, pub min_p: Option<f32>,
pub system_prompt: Option<String>, pub system_prompt: Option<String>,
pub persona_id: Option<String>, pub persona_id: Option<String>,
pub prompt_eval_count: Option<i32>,
pub eval_count: Option<i32>,
} }
// --- Libraries --- // --- Libraries ---
+2
View File
@@ -223,6 +223,8 @@ diesel::table! {
min_p -> Nullable<Float>, min_p -> Nullable<Float>,
system_prompt -> Nullable<Text>, system_prompt -> Nullable<Text>,
persona_id -> Nullable<Text>, persona_id -> Nullable<Text>,
prompt_eval_count -> Nullable<Integer>,
eval_count -> Nullable<Integer>,
} }
} }