feat: Calendar Agent + IoT Agent design + DB migration

- Deployed Calendar Agent (n8n ID: 4ZIEGck9n4l5qaDt)
  - 12 Google Calendars via HA proxy, cron 06:30
  - GPT-4.1 batch classification -> memory_facts
  - Telegram daily briefing
- DB: added source_ref column + dedup index on memory_facts
- DB: created ha_sensor_config table (IoT Agent sensor allowlist)
  - 9 seed entries (Pixel 10, Pixel Watch, EY HP, Spotify, GPS)
- README: full IoT Agent design documentation
  - Sensor allowlist (regex), LLM-based activity inference
  - Three-layer data flow, confidence-gated clarification
- README: Calendar Agent design + workflow diagram
- README: updated infra table, ADR broker, credentials
- CHANGELOG: Calendar Agent milestone

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-03-21 13:45:12 +00:00
parent 841d3a93f6
commit 90d9faacca
3 changed files with 258 additions and 34 deletions

View File

@@ -56,6 +56,7 @@ CREATE TABLE IF NOT EXISTS memory_facts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id TEXT NOT NULL DEFAULT 'martin',
source TEXT NOT NULL, -- 'email' | 'calendar' | 'iot' | 'paperless' | 'n8n' | ...
source_ref TEXT, -- ID esterno per dedup (es. UID evento Google, thread_id email)
category TEXT, -- 'finance' | 'personal' | 'work' | 'health' | ...
subject TEXT,
detail JSONB, -- payload flessibile per-source
@@ -77,6 +78,15 @@ CREATE INDEX IF NOT EXISTS idx_memory_facts_action
ON memory_facts(user_id, action_required)
WHERE action_required = true;
CREATE INDEX IF NOT EXISTS idx_memory_facts_source_ref
ON memory_facts(source_ref)
WHERE source_ref IS NOT NULL;
-- Dedup: prevents duplicate inserts for same event (used by Calendar Agent and others)
CREATE UNIQUE INDEX IF NOT EXISTS memory_facts_dedup_idx
ON memory_facts(user_id, source, source_ref)
WHERE source_ref IS NOT NULL;
-- =============================================================================
-- 3. FINANCE_DOCUMENTS
@@ -163,8 +173,42 @@ CREATE INDEX IF NOT EXISTS idx_agent_msgs_expires
WHERE expires_at IS NOT NULL AND arbiter_decision IS NULL;
-- =============================================================================
-- 6. HA_SENSOR_CONFIG
-- Allowlist dinamica dei sensori Home Assistant monitorati dall'IoT Agent.
-- Pattern = regex, matchato contro gli entity_id di Home Assistant.
-- Evita regole hardcoded nel workflow — aggiungere sensori = INSERT.
-- =============================================================================
CREATE TABLE IF NOT EXISTS ha_sensor_config (
id SERIAL PRIMARY KEY,
pattern TEXT NOT NULL, -- regex pattern (es. 'sensor\.pixel_10_.*')
user_id TEXT NOT NULL DEFAULT 'martin',
group_name TEXT NOT NULL, -- 'mobile_device' | 'work_presence' | 'entertainment' | ...
description TEXT,
active BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMP NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_ha_sensor_config_user
ON ha_sensor_config(user_id, active);
-- Seed: sensori significativi per Martin
INSERT INTO ha_sensor_config (pattern, user_id, group_name, description) VALUES
('sensor\.pixel_10_.*', 'martin', 'mobile_device', 'Tutti i sensori Pixel 10'),
('binary_sensor\.pixel_10_.*', 'martin', 'mobile_device', 'Sensori binari Pixel 10'),
('device_tracker\.ey_hp', 'martin', 'work_presence', 'Laptop EY (router tracker)'),
('media_player\.spotify_martin', 'martin', 'entertainment', 'Spotify Martin'),
('person\.martin_tahiraj', 'martin', 'presence', 'Zona GPS Martin'),
('sensor\.pixel_watch_.*', 'martin', 'wearable', 'Pixel Watch 4 (futuro)'),
('sensor\.pixel_10_heart_rate', 'martin', 'health', 'Frequenza cardiaca'),
('sensor\.pixel_10_daily_steps', 'martin', 'health', 'Passi giornalieri'),
('sensor\.pixel_10_sleep_duration', 'martin', 'health', 'Durata sonno'),
('sensor\.pixel_10_next_alarm', 'martin', 'routine', 'Prossima sveglia')
ON CONFLICT DO NOTHING;
-- =============================================================================
-- Fine script
-- =============================================================================
\echo '✅ Schema pompeo applicato correttamente.'
\echo ' Tabelle: user_profile, memory_facts, finance_documents, behavioral_context, agent_messages'
\echo ' Tabelle: user_profile, memory_facts, finance_documents, behavioral_context, agent_messages, ha_sensor_config'