Apollo Places: enrich insights with personal place name + notes
Optional integration with the sibling Apollo project's user-defined Places (name + lat/lon + radius_m + description + category). When APOLLO_API_BASE_URL is set, the per-photo location resolver folds the most-specific containing Place into the LLM prompt's location string — "Home (My house in Cambridge) — near Cambridge, MA" rather than the city name alone. Smallest-radius wins; Apollo sorts server-side via /api/places/contains, so the carousel badge in Apollo and the prompt string here always agree. Adds an agentic tool `get_personal_place_at(latitude, longitude)` that the LLM can call during chat continuation. Tool description tells the model the call returns the user's free-text notes, not just a name. Deliberately narrow — no enumerate-all variant, lat/lon required. Unset APOLLO_API_BASE_URL = legacy Nominatim-only path, tool is not registered. 5 s timeout; all errors degrade silently. Tests: 5 unit tests for compose_location_string (Apollo only, Nominatim only, both, both-with-description, neither). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
31
CLAUDE.md
31
CLAUDE.md
@@ -280,6 +280,12 @@ OLLAMA_REQUEST_TIMEOUT_SECONDS=120 # Per-request generation timeout
|
||||
SMS_API_URL=http://localhost:8000 # SMS message API endpoint (default: localhost:8000)
|
||||
SMS_API_TOKEN=your-api-token # SMS API authentication token (optional)
|
||||
|
||||
# Apollo Places integration (optional). When set, photo-insight enrichment
|
||||
# folds the user's personal place name (Home, Work, Cabin, ...) into the
|
||||
# location string fed to the LLM, and the agentic loop gains a
|
||||
# `get_personal_place_at` tool. Unset = legacy Nominatim-only path.
|
||||
APOLLO_API_BASE_URL=http://apollo.lan:8000 # Base URL of the sibling Apollo backend
|
||||
|
||||
# OpenRouter (Hybrid Backend) - keeps embeddings + vision local, routes chat to OpenRouter
|
||||
OPENROUTER_API_KEY=sk-or-... # Required to enable hybrid backend
|
||||
OPENROUTER_DEFAULT_MODEL=anthropic/claude-sonnet-4 # Used when client doesn't pick a model
|
||||
@@ -371,6 +377,31 @@ Configurable env:
|
||||
- `AGENTIC_CHAT_MAX_ITERATIONS` — cap on tool-calling iterations per turn
|
||||
(default 6). Per-request `max_iterations` is clamped to this cap.
|
||||
|
||||
**Apollo Places integration (optional):**
|
||||
|
||||
The sibling Apollo project (personal location-history viewer) owns
|
||||
user-defined Places: `name + lat/lon + radius_m + description (+ optional
|
||||
category)`. When `APOLLO_API_BASE_URL` is set, ImageApi queries
|
||||
`/api/places/contains?lat=&lon=` to enrich the LLM prompt's location
|
||||
string. See `src/ai/apollo_client.rs` and `src/ai/insight_generator.rs`:
|
||||
|
||||
- **Auto-enrichment** (always on when configured): the per-photo location
|
||||
resolver folds the most-specific containing Place ("Home — near
|
||||
Cambridge, MA" or "Home (My house in Cambridge) — near Cambridge, MA"
|
||||
when a description is set) into the location field of `combine_contexts`.
|
||||
Smallest-radius wins — Apollo sorts server-side, this code takes `[0]`.
|
||||
- **Agentic tool** `get_personal_place_at(latitude, longitude)`: registered
|
||||
alongside `reverse_geocode` only when `apollo_enabled()` returns true.
|
||||
Returns "- Name [category]: description (radius N m)" lines, smallest
|
||||
radius first. The tool is **deliberately narrow** — no enumerate-all
|
||||
variant; auto-enrichment covers the photo-context path and the agentic
|
||||
tool covers ad-hoc lat/lon questions in chat continuation.
|
||||
|
||||
Failure modes degrade silently to the legacy Nominatim path: 5 s timeout,
|
||||
errors logged at `warn`, empty results returned. Apollo's routes are
|
||||
unauthenticated (single-user, LAN-trust); add JWT auth here + on Apollo's
|
||||
side if exposing beyond a trusted network.
|
||||
|
||||
## Dependencies of Note
|
||||
|
||||
### Rust crates
|
||||
|
||||
Reference in New Issue
Block a user