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:
@@ -31,6 +31,44 @@ diesel::table! {
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
entities (id) {
|
||||
id -> Integer,
|
||||
name -> Text,
|
||||
entity_type -> Text,
|
||||
description -> Text,
|
||||
embedding -> Nullable<Binary>,
|
||||
confidence -> Float,
|
||||
status -> Text,
|
||||
created_at -> BigInt,
|
||||
updated_at -> BigInt,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
entity_facts (id) {
|
||||
id -> Integer,
|
||||
subject_entity_id -> Integer,
|
||||
predicate -> Text,
|
||||
object_entity_id -> Nullable<Integer>,
|
||||
object_value -> Nullable<Text>,
|
||||
source_photo -> Nullable<Text>,
|
||||
source_insight_id -> Nullable<Integer>,
|
||||
confidence -> Float,
|
||||
status -> Text,
|
||||
created_at -> BigInt,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
entity_photo_links (id) {
|
||||
id -> Integer,
|
||||
entity_id -> Integer,
|
||||
file_path -> Text,
|
||||
role -> Text,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
favorites (id) {
|
||||
id -> Integer,
|
||||
@@ -112,6 +150,7 @@ diesel::table! {
|
||||
summary -> Text,
|
||||
generated_at -> BigInt,
|
||||
model_version -> Text,
|
||||
is_current -> Bool,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,11 +204,16 @@ diesel::table! {
|
||||
}
|
||||
}
|
||||
|
||||
diesel::joinable!(entity_facts -> photo_insights (source_insight_id));
|
||||
diesel::joinable!(entity_photo_links -> entities (entity_id));
|
||||
diesel::joinable!(tagged_photo -> tags (tag_id));
|
||||
|
||||
diesel::allow_tables_to_appear_in_same_query!(
|
||||
calendar_events,
|
||||
daily_conversation_summaries,
|
||||
entities,
|
||||
entity_facts,
|
||||
entity_photo_links,
|
||||
favorites,
|
||||
image_exif,
|
||||
knowledge_embeddings,
|
||||
|
||||
Reference in New Issue
Block a user