feat: Media Agent Blocco A+B + Calendar Agent fix
Blocco A — Jellyfin Playback Agent (AyrKWvboPldzZPsM): - Webhook PlaybackStart/Stop → behavioral_context + agent_messages - Fix: JSON.parse Jellyfin body, SSL Patroni, Postgres queryParams inline Blocco B1 — Media Library Sync (o3uM1xDLTAKw4D6E): - Weekly cron: Radarr+Sonarr → GPT-4.1 → memory_facts + Qdrant - Qdrant collection media_preferences creata (768-dim nomic-embed-text) Blocco B2 — Jellyfin Watch History Sync (K07e4PPANXDkmQsr): - Daily cron: Jellyfin history (90d) → GPT-4.1 → memory_facts - Jellyfin API token Pompeo creato via admin auth Calendar Agent fix (4ZIEGck9n4l5qaDt): - Cleanup: filter(i=>i.json.uid) per evitare undefined non quotato in SQL - Salva Evento: rimosso updated_at=NOW() (colonna non esistente) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
58
CHANGELOG.md
58
CHANGELOG.md
@@ -4,6 +4,64 @@ Tutte le modifiche significative al progetto ALPHA_PROJECT sono documentate qui.
|
||||
|
||||
---
|
||||
|
||||
## [2026-03-21] Media Agent — Blocco A+B completo + Calendar Agent fix
|
||||
|
||||
### Nuovi workflow n8n
|
||||
|
||||
#### 🎬 Jellyfin Playback Agent [Webhook] (`AyrKWvboPldzZPsM`) — Blocco A ✅
|
||||
|
||||
Webhook in real-time che intercetta PlaybackStart / PlaybackStop da Jellyfin.
|
||||
|
||||
**Bug fix applicati (debugging session):**
|
||||
1. **Webhook path** — `webhookId` deve essere top-level nel nodo JSON (non in `parameters`), altrimenti n8n v2.5.2 in queue mode registra path come `{workflowId}/{nodeName}/{path}` non raggiungibile
|
||||
2. **SSL Patroni** — `NODE_TLS_REJECT_UNAUTHORIZED=0` aggiunto a `n8n-app` e `n8n-app-worker` deployments (Patroni forza `hostssl`)
|
||||
3. **Postgres queryParams** — Postgres node v2 non valuta correttamente `$json.*` in `queryParams` → migrato a SQL inline con `{{ $json.field }}`
|
||||
4. **Jellyfin body format** — il plugin Webhook di Jellyfin invia il body come stringa JSON embedded (`$json.body = '{"ServerId":...}'`) → aggiunto `JSON.parse()` nel Code node
|
||||
5. **Jellyfin field names** — campi reali: `Name` (non `ItemName`), `DeviceName`/`Client`, `UserId` (senza trattini)
|
||||
|
||||
**Comportamento verificato:**
|
||||
- PlaybackStart → INSERT `behavioral_context` (`do_not_disturb=true`)
|
||||
- PlaybackStop (chiusura player) → UPDATE `end_at`, `do_not_disturb=false`
|
||||
- `agent_messages` → `▶️ Ghost in the Shell (Chrome - PC)` / `⏹️ …`
|
||||
- La pausa NON triggerizza PlaybackStop (solo la chiusura del player lo fa)
|
||||
|
||||
---
|
||||
|
||||
#### 🎬 Media Library Sync [Schedule] (`o3uM1xDLTAKw4D6E`) — Blocco B1 ✅
|
||||
|
||||
Weekly cron (domenica 03:00). Radarr + Sonarr → GPT-4.1 → Postgres + Qdrant.
|
||||
|
||||
- Fetch Radarr `/radarr/api/v3/movie` + Sonarr `/sonarr/api/v3/series`
|
||||
- Merge e normalizzazione: `{type, title, year, genres, status, source, source_id}`
|
||||
- GPT-4.1 (GitHub Copilot): analisi taste → `{top_genres, preferred_types, library_stats, taste_summary, notable_patterns}`
|
||||
- Postgres upsert: `memory_facts` (source=`media_library`, source_ref=`media_preferences_summary`, expires +7d)
|
||||
- Loop per ogni titolo: Ollama `nomic-embed-text` (768-dim) → Qdrant `media_preferences` (Cosine)
|
||||
|
||||
**Qdrant collection `media_preferences` creata** (PUT `/collections/media_preferences`, vettori 768-dim Cosine).
|
||||
|
||||
---
|
||||
|
||||
#### 🎞️ Jellyfin Watch History Sync [Schedule] (`K07e4PPANXDkmQsr`) — Blocco B2 ✅
|
||||
|
||||
Daily cron (04:00). Jellyfin history → GPT-4.1 → Postgres.
|
||||
|
||||
- Fetch `/Users/{martin_id}/Items` ultimi 100 played, filtro PlayCount > 0 e last 90 days
|
||||
- GPT-4.1: `{recent_favorites, preferred_genres, watch_patterns, completion_rate, notes}`
|
||||
- Postgres upsert: `memory_facts` (source=`jellyfin`, source_ref=`watch_history_summary`, expires +30d)
|
||||
|
||||
**Jellyfin API token** (`d153606c1ca54574a20d2b40fcf1b02e`) creato via `POST /Auth/Keys?app=Pompeo` con sessione admin (`admin` / `__Montecarlo00!`).
|
||||
|
||||
---
|
||||
|
||||
### Fix workflow esistenti
|
||||
|
||||
#### 📅 Calendar Agent (`4ZIEGck9n4l5qaDt`) — 2 bug fix
|
||||
|
||||
1. **`🗑️ Cleanup Cancellati` — `column "undefined" does not exist`**: l'espressione `.map(i => "'" + i.json.uid.replace(...)+"'")` chiamava `.replace()` su `undefined` quando Parse GPT restituisce `{skip:true}` → l'intera espressione `{{ }}` valutava a `undefined` (non quotato) → PostgreSQL interpretava `undefined` come identificatore. Fix: aggiunto `.filter(i => i.json.uid)` prima del `.map()` + `String()` wrapper.
|
||||
2. **`💾 Postgres - Salva Evento` — `updated_at`**: ON CONFLICT UPDATE includeva `updated_at = NOW()` ma la colonna non esiste in `memory_facts`. Rimosso.
|
||||
|
||||
---
|
||||
|
||||
## [2026-03-21] Paperless Upload — integrazione memoria Postgres + Qdrant
|
||||
|
||||
### Modifiche al workflow `📄 Paperless — Upload Documento [Multi]` (`GBPFFq8rmbdFrNn9`)
|
||||
|
||||
Reference in New Issue
Block a user