synops/docs/features/universell_input.md
vegard a3dfa3b254 Webhook-templates: forhåndsdefinerte mappinger for kjente tjenester (oppgave 29.6)
Legger til et template-system for webhooks som vet hvordan kjente
tjenester strukturerer sine JSON-payloads, og mapper dem til
meningsfulle node title/content/metadata.

Templates:
- github-push: Commits med repo, branch, pusher, formaterte meldinger
- github-issues: Issue-hendelser med nummer, labels, state
- github-pull-request: PR-hendelser med branch-info, merge-status
- slack-message: Slack Event API-meldinger med kanal og bruker
- ci-build: Generisk CI/CD (GitHub Actions, GitLab CI, Jenkins)

Backend:
- webhook_templates.rs: Template-definisjoner og apply-logikk
- webhook.rs: Bruker template fra webhook-nodens metadata.template_id
- webhook_admin.rs: GET /admin/webhooks/templates, POST set_template,
  template_id i create og list

Frontend:
- Template-velger i opprett-skjema og på hver webhook-kort
- Kan bytte template på eksisterende webhooks

6 unit-tester for alle templates. Verifisert med curl mot live endpoint.
2026-03-18 22:10:33 +00:00

5.5 KiB

Feature: Universell input — alle modaliteter blir noder

Prinsipp

Alt som kommer inn i Synops ender som en node. Modaliteten er transport — tekst, tale, bilde, URL, epost, webhook, RSS, video, lokasjon, tegning, kalender. Noden er det som lever videre.

Modaliteter

Allerede implementert

Modalitet Input Node-type Prosessering
Tekst Tastatur → editor/chat content
Tale Mikrofon → Whisper content + media STT → tekst i content
Bilde Kamera/fil → CAS media Valgfri AI-beskrivelse
Fil Drag-and-drop/upload media MIME-deteksjon
URL Lim inn → synops-clip content Readability-parsing
Epost synops-mail content Avsender-verifisering
Drag-and-drop Interaksjonsmodell edge / ny node Kontekstavhengig

Nye modaliteter

Skjermklipp

Paste screenshot fra clipboard. Lavterskel visuell input.

Ctrl+V (bilde i clipboard)
  → Frontend detekterer ClipboardEvent med image
  → Upload til CAS → media-node
  → Valgfri: synops-ai "beskriv dette bildet" → description i metadata
  → Inline i chat/editor som bilde med bildetekst

Bruk: bug-rapportering, visuell referanse, hurtig deling.

RSS/Feed-abonnement

Automatisk innhenting fra eksterne kilder.

synops-feed --url https://nrk.no/nyheter/rss --collection-id <uuid>
  → Poller hvert 30. minutt
  → Nye entries → content-noder med source_url
  → AI-oppsummering valgfritt
  → Paywall-deteksjon gjenbrukt fra synops-clip

Perfekt som orkestrering: "Overvåk denne kilden og varsle redaksjonen om relevante saker."

Webhook (universell ekstern input)

Alt som ikke er menneske kan prate med Synops.

POST /api/webhook/<token>
  Content-Type: application/json
  { "title": "Build passed", "status": "success", ... }

  → Vaktmesteren validerer token
  → Oppretter content-node med payload i metadata
  → belongs_to-edge til målsamling

Webhook-templates (forhåndsdefinerte mappinger) for kjente tjenester:

  • GitHub Push: [repo] Push til branch — N commit(s) med formaterte commit-meldinger
  • GitHub Issues: [repo] Issue #N action: title med labels og state
  • GitHub PR: [repo] PR #N action: title med branch-info og merge-status
  • Slack: Slack #channel — user med meldingstekst
  • CI/CD: [repo] Build STATUS: pipeline med branch, varighet og lenke

Template-id lagres i webhook-nodens metadata (metadata.template_id). Admin-API: GET /admin/webhooks/templates (liste), POST /admin/webhooks/set_template. Uten template brukes generisk ekstraksjon (title/content/body-felt).

Video

Opptak direkte i nettleseren.

[● Opptak] → MediaRecorder API → webcam eller skjerm
  → Upload til CAS → media-node
  → Valgfri: synops-video for transcode + thumbnail

Bruk: korte videomeldinger, skjermopptak for feedback, møte-opptak uten LiveKit.

Geolokasjon

"Jeg er her" som input.

[📍 Del posisjon] → Geolocation API
  → Node med metadata.location: { lat, lon }
  → Kart-visning i node-detaljer (OpenStreetMap)
  → Valgfri: reverse geocoding for adresse

Bruk: feltarbeid, lokasjonstagging av innhold, "dette skjedde her".

Håndskrift/tegning

Rask skisse som input — ikke whiteboard, men post-it.

[✏️ Tegn] → Enkel canvas-flate
  → Eksporter som PNG → CAS → media-node
  → Inline i chat/editor

Bruk: hurtig-skisse, diagram på mobil, visuell idé.

Kalender-import

Synkroniser med eksisterende kalendere.

synops-calendar --file møter.ics --collection-id <uuid>
  → Parser ICS → noder med scheduled-edges
  → Duplikatdeteksjon via UID
  → Oppdatering ved re-import

CalDAV-abonnement for kontinuerlig synk med Google/Outlook.

Universell input-komponent

Alle modaliteter er tilgjengelige fra samme input-komponent:

┌──────────────────────────────────────────┐
│ Skriv noe...                        [↑] │
│                                          │
│ 🎤  📷  📎  🔗  📍  ✏️  📹             │
│ tale bilde fil url pos tegn video        │
└──────────────────────────────────────────┘

Ikonrad under input-feltet. Klikk → aktiver modalitet. Resultat havner alltid som node — inline i chat, eller som frittstående i samlingen.

Alt er noder

Uansett modalitet:

Tekst      → content-node (content-felt)
Tale       → media-node + content-node (etter STT)
Bilde      → media-node (metadata: cas_hash, mime)
Skjermklipp → media-node (metadata: source=screenshot)
Video      → media-node (metadata: cas_hash, duration)
URL        → content-node (metadata: source_url)
RSS-entry  → content-node (metadata: source_url, feed_url)
Webhook    → content-node (metadata: webhook_id, payload)
Lokasjon   → content-node (metadata: location)
Tegning    → media-node (metadata: source=drawing)
Kalender   → content-node + scheduled-edge
Epost      → content-node (metadata: from, subject)

Edges kobler dem til kontekst (samling, samtale, person). Visninger (kanban, kalender, graf) viser dem riktig basert på edges og metadata — ikke basert på modalitet.

Bygger på

  • docs/retninger/universell_input.md — tre primitiver
  • docs/concepts/orkestrering.md — RSS/webhook som triggere
  • docs/features/nodereferanser.md — n:-lenking av alle noder
  • docs/retninger/interaksjonsmodell.md — drag-and-drop