use anyhow::Result; use searchi_core::SearchIndex; use searchi_service::{FfmpegTools, HybridSearch, MediaLimits, SearchOptions, SemanticOrigin}; use std::{fs, path::PathBuf}; #[test] #[ignore = "Requires verified Google CPU worker/model and FFmpeg fixtures"] fn explicit_media_requests_do_not_fall_back_to_unrelated_channels() -> Result<()> { assert_eq!(std::env::var("SEARCHI_FORCE_CPU")?, "1"); let model = std::env::var_os("SEARCHI_GEMMA_MODEL_DIR").expect("Set model directory"); let worker = std::env::var_os("SEARCHI_GEMMA_WORKER").expect("Set worker path"); let tools = FfmpegTools { ffmpeg: std::env::var_os("SEARCHI_TEST_FFMPEG") .expect("Set FFmpeg") .into(), ffprobe: std::env::var_os("SEARCHI_TEST_FFPROBE") .expect("Set FFprobe") .into(), }; let fixture = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../fixtures/media/assets/image01.jpg"); let temp = tempfile::tempdir()?; let corpus = temp.path().join("corpus"); fs::create_dir(&corpus)?; fs::copy(fixture, corpus.join("cat.jpg"))?; let database = temp.path().join("index.db"); let mut lexical = SearchIndex::open(&database)?; lexical.index_folder(&corpus)?; let mut indexer = HybridSearch::open(&database, &model, &worker, 1)?; let report = indexer.index_embeddings_with_media(&tools, &MediaLimits::default())?; assert!(report.failures.is_empty(), "{report:?}"); assert_eq!(report.media_files, 1); drop(indexer); let mut search = HybridSearch::open_query(&database, &model, &worker, 1)?; let options = SearchOptions::default(); // The unfiltered real model does return the nearest photo for these requests. // The correction rejects its wrong channel, not its similarity score. for query in [ "music with violin", "audio of thunder", "someone mentions a contract", "video of a boat", "Musik mit Klavier", "Film mit einem Wasserfall", ] { assert!( !search .search_semantic_with_origin(query, 10, &options, SemanticOrigin::All)? .is_empty(), "{query}" ); assert!( search.search_semantic(query, 10, &options)?.is_empty(), "{query}" ); } for query in ["photo of a cat indoors", "Bild einer Katze", "cat indoors"] { let hits = search.search_semantic(query, 10, &options)?; assert_eq!(hits[0].filename, "cat.jpg", "{query}"); assert_eq!(hits[0].match_kind, "semantic_image", "{query}"); } assert_eq!( search.search("cat.jpg", 1, &options)?[0].match_kind, "exact_filename" ); Ok(()) } #[test] #[ignore = "Requires verified Google CPU worker/model and FFmpeg fixtures"] fn explicit_code_intent_preserves_code_among_real_audio_candidates() -> Result<()> { assert_eq!(std::env::var("SEARCHI_FORCE_CPU")?, "1"); let model = std::env::var_os("SEARCHI_GEMMA_MODEL_DIR").expect("Set model directory"); let worker = std::env::var_os("SEARCHI_GEMMA_WORKER").expect("Set worker path"); let tools = FfmpegTools { ffmpeg: std::env::var_os("SEARCHI_TEST_FFMPEG") .expect("Set FFmpeg") .into(), ffprobe: std::env::var_os("SEARCHI_TEST_FFPROBE") .expect("Set FFprobe") .into(), }; let fixture = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../fixtures"); let temp = tempfile::tempdir()?; let corpus = temp.path().join("corpus"); fs::create_dir(&corpus)?; // Preserve the unchanged diagnostic implementation and actual licensed sound. fs::copy( fixture.join("mixed/sources/crates__searchi-service__src__routing.rs"), corpus.join("routing.rs"), )?; fs::copy( fixture.join("media/assets/sound02.mp3"), corpus.join("sound.mp3"), )?; let database = temp.path().join("index.db"); let mut lexical = SearchIndex::open(&database)?; lexical.index_folder(&corpus)?; let mut indexer = HybridSearch::open(&database, &model, &worker, 1)?; let report = indexer.index_embeddings_with_media(&tools, &MediaLimits::default())?; assert!(report.failures.is_empty(), "{report:?}"); assert_eq!(report.media_files, 1); drop(indexer); let mut search = HybridSearch::open_query(&database, &model, &worker, 1)?; let query = "code that chooses audio search when a query mentions speech"; let options = SearchOptions::default(); let audio = search.search_semantic_with_origin(query, 20, &options, SemanticOrigin::Audio)?; assert!( !audio.is_empty(), "The old exclusive audio lane must qualify" ); assert!(audio.iter().all(|hit| hit.filename == "sound.mp3")); let hits = search.search_semantic(query, 20, &options)?; assert!( hits.iter().any(|hit| hit.filename == "routing.rs"), "Explicit code intent lost its semantic implementation: {hits:?}" ); Ok(()) }