Unified NL search Phase 1: NL→structured-query translator + forward geocoding

Foundation for the /photos/search/unified endpoint (Phase 2). Two new,
fully unit-tested pieces, not yet wired into a route (allow-until-wired,
mirroring llm_client.rs):

- ai/nl_query.rs: translate a free-text query into a StructuredQuery via one
  grounded LLM call. Two-stage — the model emits names/ISO dates, then a pure
  resolve step maps tag names against the real vocab and converts dates to
  unix seconds. Hallucinated (non-vocab) tags are surfaced in unmatched_tags
  rather than silently used as hard filters — the anti-noise guard. 12 tests.

- geo::forward_geocode + bbox_to_circle: resolve a place name to a circle via
  Nominatim /search, collapsing the bounding box to centroid + circumscribing
  radius so "Portland" and "Italy" both map onto the existing gps circle
  filter with no schema change. Radius is the max centroid-to-corner distance
  (corners aren't equidistant on a sphere). 4 tests.

fmt + clippy clean; 19 new tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Cameron CordesandClaude Opus 4.8 authored and Cameron committed 2026-06-29 12:39:16 -04:00
1 parent e9d04afd4b
commit 09ccb347c7
3 files changed
+595

No files matched your search

+1
View File
@@ -10,6 +10,7 @@ pub mod insight_generator;
pub mod llamacpp;
pub mod llm_client;
pub mod local_llm;
pub mod nl_query;
pub mod ollama;
pub mod openrouter;
pub mod pronunciation;