Unified NL search Phase 2: /photos/search/unified endpoint
Composes the two existing engines (Path A orchestration): - Translate NL -> StructuredQuery via local LLM, respecting LLM_BACKEND (resolve_backend(Local) -> ollama or llama-swap; no hybrid). - Forward-geocode the place name into a gps circle. - Structured filters (tags/EXIF/geo/date/media) build a candidate set of EXIF rows; CLIP ranks within it, joined by content_hash. Degenerate cases match existing behavior: semantic-only -> plain CLIP; filters-only -> date-sorted. - Echoes the interpreted query (incl. resolved place) for editable client chips. Refactor: extracted reusable cores from clip_search (score_photos, resolve_hits, parse_library_scope, score_error_response) shared by both endpoints. Removed the Phase 1 allow-until-wired attributes now that nl_query + geo are consumed. fmt + clippy clean; 23 backend tests pass (7 geo, 12 nl_query, 4 unified). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
09ccb347c7
commit
fd00dc936a
6 files changed
+675
-198
No files matched your search
@@ -54,6 +54,7 @@ mod perceptual_hash;
|
||||
mod state;
|
||||
mod tags;
|
||||
mod thumbnails;
|
||||
mod unified_search;
|
||||
mod utils;
|
||||
mod video;
|
||||
mod watcher;
|
||||
@@ -333,6 +334,13 @@ fn main() -> std::io::Result<()> {
|
||||
web::resource("/photos/search")
|
||||
.route(web::get().to(clip_search::search_photos)),
|
||||
)
|
||||
.service(
|
||||
// Unified natural-language search: LLM translates the
|
||||
// query into structured filters + a semantic term, then
|
||||
// filters constrain and CLIP ranks. See src/unified_search.rs.
|
||||
web::resource("/photos/search/unified")
|
||||
.route(web::get().to(unified_search::unified_search::<SqliteTagDao>)),
|
||||
)
|
||||
.service(web::resource("/file/move").post(move_file::<RealFileSystem>))
|
||||
.service(handlers::image::get_image)
|
||||
.service(handlers::image::upload_image)
|
||||
|
||||
Reference in new issue
Block a user