002-agentic-insights #53

Merged
cameron merged 13 commits from 002-agentic-insights into master 2026-04-02 16:46:07 +00:00

13 Commits

Author SHA1 Message Date
Cameron
54a49a8562 fix: agentic loop robustness — tool arg sanitisation, geocoding, better errors
- Sanitise tool call arguments before re-sending in conversation history: non-object values (bool, string, null) that some models produce are normalised to {} to prevent Ollama 500s
- Map 'error parsing tool call' Ollama 500 to HTTP 400 with a descriptive message listing compatible models (llama3.1, llama3.2, qwen2.5, mistral-nemo)
- Add reverse_geocode tool backed by existing Nominatim helper; description hints model can chain it after get_location_history results
- Make get_sms_messages contact parameter optional (was required, forcing the model to guess); executor now passes None to fall back to all-contacts search
- Log tool result outcomes at warn level for errors/empty results, info for successes; log SMS API errors with full detail; log full request body on Ollama 500
- Strengthen system prompt to require 3-4 tool calls before final answer
- Try fallback server when checking model capabilities (primary-only check caused 500 for models only on fallback)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 23:58:01 -04:00
Cameron
c1b6013412 chore: cargo fmt + clippy fix for collapsed if-let chain (T017)
- cargo fmt applied across all modified source files
- Collapse nested if let Some / if !is_empty into a single let-chain (clippy::collapsible_match)
- All other warnings are pre-existing dead-code lint on unused trait methods

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 23:09:58 -04:00
Cameron
5c9f5c7d0b feat: add model-availability validation to agentic insight generation (T009-T011)
- Verify custom model exists on at least one configured server before starting agentic loop; returns HTTP 400 with descriptive error if not found
- has_tool_calling field auto-serialised in GET /insights/models via existing ModelCapabilities Serialize derive
- model_version stored from OllamaClient.primary_model (already correct in T006 implementation)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 23:07:43 -04:00
Cameron
091327e5d9 feat: add POST /insights/generate/agentic handler and route
Register the agentic insight endpoint that validates tool-calling capability,
runs the agentic loop, and returns the stored PhotoInsightResponse. Returns 400
for unsupported models, 500 for other errors. Max iterations configurable via
AGENTIC_MAX_ITERATIONS env var (default 10).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 23:01:25 -04:00
Cameron
7615b9c99b feat: add tool executors and generate_agentic_insight_for_photo() to InsightGenerator
Add 6 tool executor methods (search_rag, get_sms_messages, get_calendar_events,
get_location_history, get_file_tags, describe_photo) and the agentic loop that
uses Ollama's chat_with_tools API to let the model decide which context to gather
before writing the final photo insight.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 23:00:41 -04:00
Cameron
5e5a2a3167 feat: add tool-calling types, chat_with_tools(), and has_tool_calling capability detection
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 22:55:20 -04:00
Cameron
8196ef94a0 feat: photo-first RAG enrichment — early vision description + tags in RAG and search context
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 17:23:49 -04:00
Cameron
e58b8fe743 feat: add enrichment parameter to gather_search_context() replacing weak metadata query
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 17:17:21 -04:00
Cameron
c0d27d0b9e feat: add Tags section to combine_contexts() for insight context
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 17:14:00 -04:00
Cameron
8ecd3c6cf8 refactor: use Arc<Mutex<SqliteConnection>> in SqliteTagDao, remove unsafe impl Sync
Aligns SqliteTagDao with the pattern used by SqliteExifDao and SqliteInsightDao.
The unsafe impl Sync workaround is no longer needed since Arc<Mutex<>> provides
safe interior mutability and automatic Sync derivation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 17:10:11 -04:00
Cameron
387ce23afd feat: add tag_dao to InsightGenerator for tag-based context enrichment
Threads SqliteTagDao through InsightGenerator and AppState (both default
and test_state). Adds Send+Sync bounds to TagDao trait with unsafe impls
for SqliteTagDao (always Mutex-protected) and TestTagDao (single-threaded).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 16:59:39 -04:00
Cameron
b31b4b903c refactor: use &str for generate_photo_description image parameter
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 16:56:27 -04:00
Cameron
dd0715c081 feat: add generate_photo_description() to OllamaClient for RAG enrichment
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 16:53:34 -04:00