From 3f6ad9853c52e1294baad58cb679646f88819194 Mon Sep 17 00:00:00 2001 From: oabrivard Date: Mon, 23 Mar 2026 23:16:06 +0100 Subject: [PATCH] feat: build_search_prompt accepts recent_domains for source diversity Co-Authored-By: Claude Sonnet 4.6 --- backend/src/services/prompts.rs | 53 +++++++++++++++++++++++++------ backend/src/services/synthesis.rs | 2 +- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/backend/src/services/prompts.rs b/backend/src/services/prompts.rs index e72270a..20b8a6a 100644 --- a/backend/src/services/prompts.rs +++ b/backend/src/services/prompts.rs @@ -19,10 +19,12 @@ use crate::models::synthesis::ScrapedNewsItem; /// * `settings` — User's configured settings (theme, categories, etc.) /// * `sources` — User's custom sources to prioritize /// * `current_date` — Formatted date string for the prompt +/// * `recent_domains` — Domains used in recent syntheses to avoid if possible pub fn build_search_prompt( settings: &UserSettings, sources: &[Source], current_date: &str, + recent_domains: &[String], ) -> (String, String) { let sources_text = if sources.is_empty() { String::new() @@ -88,6 +90,16 @@ pub fn build_search_prompt( max_items = settings.max_items_per_category, ); + let user_prompt = if recent_domains.is_empty() { + user_prompt + } else { + let domains_list = recent_domains.join(", "); + format!( + "{}\n\nEvite si possible les sources deja utilisees dans les syntheses precedentes : {}.", + user_prompt, domains_list + ) + }; + (system_prompt, user_prompt) } @@ -159,21 +171,21 @@ mod tests { #[test] fn search_prompt_includes_theme() { let settings = test_settings(); - let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026"); + let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026", &[]); assert!(user_prompt.contains("Intelligence Artificielle")); } #[test] fn search_prompt_includes_date() { let settings = test_settings(); - let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026"); + let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026", &[]); assert!(user_prompt.contains("lundi 21 mars 2026")); } #[test] fn search_prompt_includes_max_age() { let settings = test_settings(); - let (system, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026"); + let (system, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026", &[]); assert!(user_prompt.contains("7 derniers jours")); assert!(system.contains("7")); } @@ -181,7 +193,7 @@ mod tests { #[test] fn search_prompt_includes_categories() { let settings = test_settings(); - let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026"); + let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026", &[]); assert!(user_prompt.contains("1. Annonces majeures")); assert!(user_prompt.contains("2. Recherche et innovation")); assert!(user_prompt.contains("2 grandes sections")); @@ -190,7 +202,7 @@ mod tests { #[test] fn search_prompt_includes_max_items() { let settings = test_settings(); - let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026"); + let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026", &[]); assert!(user_prompt.contains("4 actualites")); } @@ -214,7 +226,7 @@ mod tests { }, ]; - let (_, user_prompt) = build_search_prompt(&settings, &sources, "lundi 21 mars 2026"); + let (_, user_prompt) = build_search_prompt(&settings, &sources, "lundi 21 mars 2026", &[]); assert!(user_prompt.contains("TechCrunch (https://techcrunch.com)")); assert!(user_prompt.contains("The Verge (https://theverge.com)")); assert!(user_prompt.contains("sources personnalisees")); @@ -223,7 +235,7 @@ mod tests { #[test] fn search_prompt_no_sources_no_section() { let settings = test_settings(); - let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026"); + let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026", &[]); assert!(!user_prompt.contains("sources personnalisees")); } @@ -233,7 +245,7 @@ mod tests { settings.search_agent_behavior = "Concentre-toi sur les sources europeennes.".to_string(); - let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026"); + let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026", &[]); assert!(user_prompt.contains("Concentre-toi sur les sources europeennes.")); assert!(!user_prompt.contains("recherche Google")); } @@ -241,14 +253,14 @@ mod tests { #[test] fn search_prompt_default_behavior_when_empty() { let settings = test_settings(); - let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026"); + let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026", &[]); assert!(user_prompt.contains("recherche Google")); } #[test] fn search_prompt_warns_against_homepage_urls() { let settings = test_settings(); - let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026"); + let (_, user_prompt) = build_search_prompt(&settings, &[], "lundi 21 mars 2026", &[]); assert!(user_prompt.contains("pages d'accueil")); assert!(user_prompt.contains("articles specifiques")); } @@ -284,4 +296,25 @@ mod tests { // Should still produce a valid prompt with empty data assert!(user_prompt.contains("Donnees des articles")); } + + #[test] + fn search_prompt_includes_recent_domains_avoidance() { + let settings = test_settings(); + let sources = vec![]; + let date = "lundi 17 mars 2026"; + let domains = vec!["techcrunch.com".to_string(), "theverge.com".to_string()]; + let (_, user_prompt) = build_search_prompt(&settings, &sources, date, &domains); + assert!(user_prompt.contains("Evite si possible")); + assert!(user_prompt.contains("techcrunch.com")); + assert!(user_prompt.contains("theverge.com")); + } + + #[test] + fn search_prompt_no_avoidance_when_domains_empty() { + let settings = test_settings(); + let sources = vec![]; + let date = "lundi 17 mars 2026"; + let (_, user_prompt) = build_search_prompt(&settings, &sources, date, &[]); + assert!(!user_prompt.contains("Evite si possible")); + } } diff --git a/backend/src/services/synthesis.rs b/backend/src/services/synthesis.rs index 1436c5c..36a04a4 100644 --- a/backend/src/services/synthesis.rs +++ b/backend/src/services/synthesis.rs @@ -301,7 +301,7 @@ async fn run_generation_inner( .format("%A %d %B %Y") .to_string(); let (system_prompt, user_prompt) = - prompts::build_search_prompt(&settings, &sources, ¤t_date); + prompts::build_search_prompt(&settings, &sources, ¤t_date, &[]); let raw_results = provider .generate_search_pass(&model_research, &system_prompt, &user_prompt, &schema)