Commit Graph

342 Commits

Author SHA1 Message Date
2f4edba08c Merge pull request '003-knowledge-memory' (#55) from 003-knowledge-memory into master
Reviewed-on: #55
2026-04-21 01:54:34 +00:00
Cameron
8bc948b297 Insight prompt tweaks 2026-04-17 11:55:33 -04:00
Cameron
b7e1bdf1fd feat: add sampling param CLI flags to populate_knowledge binary
Adds --temperature, --top-p, --top-k, --min-p flags so batch runs can
tune the same sampling params now supported by the API endpoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 14:23:45 -04:00
Cameron
3059adfd37 Add missing DB migration sql for training data 2026-04-15 09:28:53 -04:00
Cameron
b599f7a34b feat: add temperature, top_p, top_k, min_p params to insight generation
Expose Ollama sampling params through the insight generation endpoints
so users can tune creativity/determinism per request. All four are
optional — omitted values fall through to the model's server-side
defaults.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 09:27:59 -04:00
Cameron
c703a47f17 Add the ability to rate insights to curate training data 2026-04-13 09:23:40 -04:00
Cameron
da16fddce3 Address path traversal and other security fixes 2026-04-10 14:58:57 -04:00
Cameron
e1c32b6584 Tweak Prompt 2026-04-10 14:30:31 -04:00
Cameron
65e938035f fix: reduce duplicate entities from weak model inconsistency
Adds normalize_entity_type() which lowercases and canonicalises synonyms
(location→place, human→person, etc.) before every upsert. The SQL lookup
now uses lower(entity_type) on both sides so existing dirty rows (Person,
Location) correctly deduplicate against normalised writes without a migration.

Adds a pre-flight similarity check in tool_store_entity: before upserting,
searches active entities of the same type using the first name token. Any
non-exact matches are appended to the tool response so the agentic loop
can choose to reuse an existing entity ID rather than create a duplicate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 18:27:09 -04:00
Cameron
bc3b313e2e feat: add populate_knowledge batch binary with configurable timeout
Adds a standalone binary that walks a directory and runs the agentic
insight loop over every image/video, skipping files already processed.
Supports --path, --model, --max-iterations, --timeout-secs, --num-ctx,
and --reprocess flags for flexible overnight/VPS batch runs.

Also adds OllamaClient::with_request_timeout() builder method so slow
large models are not cut off by the default 120s limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 16:39:46 -04:00
Cameron
da039bbc49 fix: include files without EXIF when sorting by date
Date sorting previously used a DB-level query that acted as an inner join,
silently dropping files with no image_exif row. Replace it with the existing
in-memory sort which already falls back to filename-extracted and filesystem
dates, so all files appear in sorted results.

Also removes the now-unused get_files_sorted_by_date trait method and its
SqliteExifDao implementation and test mock.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 14:43:26 -04:00
Cameron
191ccc0d77 feat: add entity-relationship knowledge memory to agentic insights
Implements persistent cross-photo knowledge memory so the agentic
insight loop can learn and recall facts about people, places, and
events across the photo collection.

Changes:
- photo_insights: drop UNIQUE(file_path) + INSERT OR REPLACE, replace
  with append-only rows + is_current flag for insight history retention
- New tables: entities, entity_facts, entity_photo_links with FK
  constraints and confidence scoring
- KnowledgeDao trait + SqliteKnowledgeDao with upsert, merge, and
  corroboration (confidence +0.1 on duplicate fact detection)
- Four new agent tools: recall_entities, recall_facts_for_photo,
  store_entity, store_fact (with object_entity_id FK support)
- Cameron entity auto-seeded with stable ID injected into system prompt
- Pre-run photo link clearing + post-loop source_insight_id backfill
- Audit REST API: GET/PATCH/DELETE /knowledge/entities/{id},
  POST /knowledge/entities/merge, GET/PATCH/DELETE /knowledge/facts/{id},
  GET /knowledge/recent

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 17:27:49 -04:00
Cameron
b2cf99c857 feat: surface Ollama context token usage in agentic insight response
Captures prompt_eval_count and eval_count from Ollama /api/chat responses
during the agentic loop and returns them in POST /insights/generate/agentic
so the frontend can display context window usage to the user.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 17:25:35 -04:00
50cf526b46 Merge pull request '002-agentic-insights' (#53) from 002-agentic-insights into master
Reviewed-on: #53
2026-04-02 16:46:06 +00:00
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
c804ee39cb Merge pull request '001-video-wall' (#52) from 001-video-wall into master
Reviewed-on: #52
2026-03-02 18:45:03 +00:00
Cameron
c05a16f7f2 Add JSON error logging for failed request deserialization
Configures a global JsonConfig error handler that logs the method, URI,
and parse error details at WARN level before returning the 400 response.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 20:02:18 -05:00
Cameron
3982c6d6d4 Fix 10-bit encode not supported error with h264_nvenc
Add format=yuv420p to preview clip filter chains to convert 10-bit
sources to 8-bit before encoding, since NVENC doesn't support 10-bit
H.264.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 19:55:36 -05:00
27a148c0aa Merge branch 'master' into 001-video-wall 2026-02-27 19:06:55 +00:00
Cameron
5975828f65 Fix incorrect frame rate handling in preview clip generation 2026-02-26 10:58:27 -05:00
Cameron
36612444c5 Ensure we re-queue pending/failed records 2026-02-26 10:42:20 -05:00
Cameron
32ece84209 Fix high framerate preview playback 2026-02-26 10:26:52 -05:00
Cameron
7d164bad81 Fix import warnings 2026-02-26 10:10:26 -05:00
Cameron
0d05033b38 Add comprehensive testing for preview clip and status handling
- Implement unit tests for PreviewClipRequest/PreviewStatusRequest serialization and deserialization.
- Add tests for PreviewDao (insert, update, batch retrieval, and status-based queries).
- Extend Actix-web integration tests for `/video/preview/status` endpoint scenarios.
- Introduce in-memory TestPreviewDao for mock database interactions.
- Update README with new config parameters for preview clips.
2026-02-26 10:06:21 -05:00
Cameron
842ed4ed66 Add Speckit and Constitution 2026-02-26 10:05:47 -05:00
Cameron
19c099360e Add VideoWall feature: server-side preview clip generation and mobile grid view
Backend (Rust/Actix-web):
- Add video_preview_clips table and PreviewDao for tracking preview generation
- Add ffmpeg preview clip generator: 10 equally-spaced 1s segments at 480p with CUDA NVENC auto-detection
- Add PreviewClipGenerator actor with semaphore-limited concurrent processing
- Add GET /video/preview and POST /video/preview/status endpoints
- Extend file watcher to detect and queue previews for new videos
- Use relative paths consistently for DB storage (matching EXIF convention)

Frontend (React Native/Expo):
- Add VideoWall grid view with 2-3 column layout of looping preview clips
- Add VideoWallItem component with ActiveVideoPlayer sub-component for lifecycle management
- Add useVideoWall hook for batch status polling with 5s refresh
- Add navigation button in grid header (visible when videos exist)
- Use TextureView surface type to fix Android z-ordering issues
- Optimize memory: players only mount while visible via FlatList windowSize
- Configure ExoPlayer buffer options and caching for short clips
- Tap to toggle audio focus, long press to open in full viewer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 19:40:17 -05:00
cdc2eef833 Merge pull request 'Build insight title from generated summary' (#51) from feature/insight-tweaks into master
Reviewed-on: #51
2026-02-24 21:21:20 +00:00
Cameron
7a0da1ab4a Build insight title from generated summary 2026-02-24 16:08:25 -05:00
1fb3441a38 Merge pull request 'Fix video rotation' (#50) from feature/fix-video-rotation into master
Reviewed-on: #50
2026-02-10 02:54:46 +00:00
Cameron
39c66d81cc Fix video rotation 2026-02-05 18:39:36 -05:00
0d5c141328 Merge pull request 'Expand temporal context window for SMS retrieval from ±2 days to ±4 days' (#49) from feature/increase-insight-context into master
Reviewed-on: #49
2026-02-05 20:57:46 +00:00
Cameron
e92513fbe9 Expand temporal context window for SMS retrieval from ±2 days to ±4 days 2026-01-29 19:48:09 -05:00
92a468233e Merge pull request 'feature/gps-map-support' (#48) from feature/gps-map-support into master
Reviewed-on: #48
2026-01-28 15:54:18 +00:00
Cameron
1efdd02eda Add GPS summary sorting
Run cargo fmt/clippy
2026-01-28 10:52:17 -05:00
Cameron
7d2a3148bb Make Memories week span sorting chronological 2026-01-26 20:51:11 -05:00
Cameron
a6cc64ece0 Bump to version 0.5.2 2026-01-26 20:05:42 -05:00
Cameron
1d2f4e3441 Add circular thumbnail creation for Map view 2026-01-26 20:04:14 -05:00
Cameron
073b5ed418 Added gps-summary endpoint for Map integration 2026-01-26 11:58:24 -05:00