Ship floating launcher, automatic discovery and bounded media search improvements

This commit is contained in:
karl committed 2026-10-14 11:44:15 +02:00
1 parent 01279a6b25
commit 521966a2ac
43 files changed
+3165 -267

No files matched your search

+16
View File
@@ -1129,11 +1129,16 @@ name = "searchi-core"
version = "0.1.0"
dependencies = [
"anyhow",
"libc",
"lopdf",
"quick-xml",
"rusqlite",
"searchi-media",
"serde",
"serde_json",
"sha2 0.10.9",
"walkdir",
"windows-sys",
"zip",
]
@@ -1192,11 +1197,22 @@ dependencies = [
"searchi-core",
"searchi-media",
"searchi-semantic",
"searchi-speech",
"serde",
"sha2 0.10.9",
"usearch",
]
[[package]]
name = "searchi-speech"
version = "0.1.0"
dependencies = [
"anyhow",
"serde",
"serde_json",
"sha2 0.10.9",
]
[[package]]
name = "serde"
version = "1.0.229"
+12 -2
View File
@@ -44,6 +44,8 @@ struct Filters {
max_duration_ms: Option<u32>,
modified_after_unix_ms: Option<i64>,
modified_before_unix_ms: Option<i64>,
media_artist: Option<String>,
media_title: Option<String>,
}
impl Filters {
fn options(self, root: &Path) -> Result<SearchOptions> {
@@ -63,6 +65,8 @@ impl Filters {
max_duration_ms: self.max_duration_ms,
modified_after_unix_ms: self.modified_after_unix_ms,
modified_before_unix_ms: self.modified_before_unix_ms,
media_artist: self.media_artist,
media_title: self.media_title,
})
}
}
@@ -87,6 +91,10 @@ fn main() -> Result<()> {
let mut lexical = SearchIndex::open(&args.db)?;
validate_database(&args.db, &root)?;
lexical.index_folder(&root)?;
ensure!(
lexical.extracted_source_hash(&root.join("Supplier Agreement.pdf").to_string_lossy())?.is_some(),
"Capture PDF was not genuinely extracted; set SEARCHI_EXTRACT_WORKER to the verified document helper"
);
lexical.prewarm()?;
let tools = FfmpegTools::new(args.ffmpeg, args.ffprobe)?;
let mut hybrid = HybridSearch::open(&args.db, &args.models, &args.worker, 1)?;
@@ -287,7 +295,7 @@ impl App {
json!({"model":"Google EmbeddingGemma 2","ready":true,"model_directory":self.models,"worker_ready":true,"downloading":false,"embedding":false,"device_policy":"cpu","error":null,"downloaded_bytes":864676480u64,"total_bytes":864676480u64,"generation":status.generation,"chunks":status.chunks,"stale":status.stale,"pending":status.pending,"warming":false,"worker_info":self.hybrid.worker_info(),"media_tools_ready":true,"media_setup_error":null,"media_failures":status.failures}),
)
}
"search_measured" | "hybrid_search_measured" => {
"search_measured" | "hybrid_search_measured" | "semantic_search_raw" => {
let query = args["query"].as_str().context("Query required")?;
ensure!(query.len() <= 4096, "Query too large");
let filters: Filters = if args["filters"].is_null() {
@@ -297,7 +305,9 @@ impl App {
};
let options = filters.options(&self.root)?;
let debug = args["debugPerformance"].as_bool().unwrap_or(false);
if name == "search_measured" {
if name == "semantic_search_raw" {
Ok(serde_json::to_value(self.hybrid.search_semantic(query, 50, &options)?)?)
} else if name == "search_measured" {
Ok(serde_json::to_value(
self.lexical
.search_with_options_measured(query, 50, &options, debug)?,