|
|
|
@ -300,8 +300,42 @@ async fn run_generation_inner(
|
|
|
|
let current_date = Utc::now()
|
|
|
|
let current_date = Utc::now()
|
|
|
|
.format("%A %d %B %Y")
|
|
|
|
.format("%A %d %B %Y")
|
|
|
|
.to_string();
|
|
|
|
.to_string();
|
|
|
|
|
|
|
|
// Step 5b: Load recently-used domains for source diversity
|
|
|
|
|
|
|
|
let recent_domains = if settings.source_diversity_window > 0 {
|
|
|
|
|
|
|
|
let recent = db::syntheses::list_for_user(
|
|
|
|
|
|
|
|
&state.pool,
|
|
|
|
|
|
|
|
user_id,
|
|
|
|
|
|
|
|
settings.source_diversity_window as i64,
|
|
|
|
|
|
|
|
0,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
.await
|
|
|
|
|
|
|
|
.unwrap_or_default();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut domains: Vec<String> = recent
|
|
|
|
|
|
|
|
.iter()
|
|
|
|
|
|
|
|
.filter_map(|s| {
|
|
|
|
|
|
|
|
serde_json::from_value::<Vec<crate::models::synthesis::NewsSection>>(
|
|
|
|
|
|
|
|
s.sections.clone(),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
.ok()
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.flat_map(|sections| {
|
|
|
|
|
|
|
|
sections
|
|
|
|
|
|
|
|
.into_iter()
|
|
|
|
|
|
|
|
.flat_map(|sec| sec.items.into_iter())
|
|
|
|
|
|
|
|
.filter_map(|item| extract_domain(&item.url))
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
domains.sort();
|
|
|
|
|
|
|
|
domains.dedup();
|
|
|
|
|
|
|
|
domains
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
Vec::new()
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
let (system_prompt, user_prompt) =
|
|
|
|
let (system_prompt, user_prompt) =
|
|
|
|
prompts::build_search_prompt(&settings, &sources, ¤t_date, &[]);
|
|
|
|
prompts::build_search_prompt(&settings, &sources, ¤t_date, &recent_domains);
|
|
|
|
|
|
|
|
|
|
|
|
let raw_results = provider
|
|
|
|
let raw_results = provider
|
|
|
|
.generate_search_pass(&model_research, &system_prompt, &user_prompt, &schema)
|
|
|
|
.generate_search_pass(&model_research, &system_prompt, &user_prompt, &schema)
|
|
|
|
|