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:
@@ -0,0 +1,3 @@
|
||||
DROP TABLE IF EXISTS entity_photo_links;
|
||||
DROP TABLE IF EXISTS entity_facts;
|
||||
DROP TABLE IF EXISTS entities;
|
||||
55
migrations/2026-04-02-000100_add_knowledge_memory/up.sql
Normal file
55
migrations/2026-04-02-000100_add_knowledge_memory/up.sql
Normal file
@@ -0,0 +1,55 @@
|
||||
-- Entity-relationship knowledge memory tables.
|
||||
-- Entities are the nodes (people, places, events, things).
|
||||
-- entity_facts are typed claims about or between entities.
|
||||
-- entity_photo_links connect entities to specific photos.
|
||||
|
||||
CREATE TABLE entities (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
entity_type TEXT NOT NULL, -- 'person' | 'place' | 'event' | 'thing'
|
||||
description TEXT NOT NULL DEFAULT '',
|
||||
embedding BLOB, -- 768-dim f32 vector; nullable if embedding service was unavailable
|
||||
confidence REAL NOT NULL DEFAULT 0.5,
|
||||
status TEXT NOT NULL DEFAULT 'active', -- 'active' | 'reviewed' | 'rejected'
|
||||
created_at BIGINT NOT NULL,
|
||||
updated_at BIGINT NOT NULL,
|
||||
UNIQUE(name, entity_type)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_entities_type ON entities(entity_type);
|
||||
CREATE INDEX idx_entities_status ON entities(status);
|
||||
CREATE INDEX idx_entities_name ON entities(name);
|
||||
|
||||
CREATE TABLE entity_facts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
subject_entity_id INTEGER NOT NULL,
|
||||
predicate TEXT NOT NULL,
|
||||
object_entity_id INTEGER, -- nullable: entity-to-entity relationship target
|
||||
object_value TEXT, -- nullable: free-text attribute value
|
||||
source_photo TEXT, -- photo path that prompted extraction (injected server-side)
|
||||
source_insight_id INTEGER, -- backfilled after insight is stored
|
||||
confidence REAL NOT NULL DEFAULT 0.6,
|
||||
status TEXT NOT NULL DEFAULT 'active', -- 'active' | 'reviewed' | 'rejected'
|
||||
created_at BIGINT NOT NULL,
|
||||
CONSTRAINT fk_ef_subject FOREIGN KEY (subject_entity_id) REFERENCES entities(id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_ef_object FOREIGN KEY (object_entity_id) REFERENCES entities(id) ON DELETE SET NULL,
|
||||
CONSTRAINT fk_ef_insight FOREIGN KEY (source_insight_id) REFERENCES photo_insights(id) ON DELETE SET NULL,
|
||||
CHECK (object_entity_id IS NOT NULL OR object_value IS NOT NULL)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_entity_facts_subject ON entity_facts(subject_entity_id);
|
||||
CREATE INDEX idx_entity_facts_predicate ON entity_facts(predicate);
|
||||
CREATE INDEX idx_entity_facts_status ON entity_facts(status);
|
||||
CREATE INDEX idx_entity_facts_source_photo ON entity_facts(source_photo);
|
||||
|
||||
CREATE TABLE entity_photo_links (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
entity_id INTEGER NOT NULL,
|
||||
file_path TEXT NOT NULL,
|
||||
role TEXT NOT NULL, -- 'subject' | 'location' | 'event' | 'thing'
|
||||
CONSTRAINT fk_epl_entity FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE,
|
||||
UNIQUE(entity_id, file_path, role)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_entity_photo_links_entity ON entity_photo_links(entity_id);
|
||||
CREATE INDEX idx_entity_photo_links_photo ON entity_photo_links(file_path);
|
||||
Reference in New Issue
Block a user