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>
This commit is contained in:
Cameron
2026-04-03 17:27:49 -04:00
parent b2cf99c857
commit 191ccc0d77
12 changed files with 1706 additions and 7 deletions

View File

@@ -0,0 +1,19 @@
-- Restore original schema, retaining only the current insight per file.
CREATE TABLE photo_insights_old (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
file_path TEXT NOT NULL UNIQUE,
title TEXT NOT NULL,
summary TEXT NOT NULL,
generated_at BIGINT NOT NULL,
model_version TEXT NOT NULL
);
INSERT INTO photo_insights_old (id, file_path, title, summary, generated_at, model_version)
SELECT id, file_path, title, summary, generated_at, model_version
FROM photo_insights
WHERE is_current = 1;
DROP TABLE photo_insights;
ALTER TABLE photo_insights_old RENAME TO photo_insights;
CREATE INDEX IF NOT EXISTS idx_photo_insights_path ON photo_insights(file_path);