synops/docs/features/ai_verktoy.md
vegard b5aa5bb243 Fjern SpacetimeDB komplett (oppgave 22.4)
SpacetimeDB er nå helt fjernet fra Synops. Sanntid håndteres av
PG LISTEN/NOTIFY + WebSocket i portvokteren (maskinrommet).

Kode fjernet:
- spacetimedb/ Rust-modul og spacetime.json
- maskinrommet/src/stdb.rs (HTTP-klient for STDB-reducers)
- frontend module_bindings/ (23 auto-genererte filer)
- spacetimedb npm-avhengighet fra package.json
- scripts/test-sanntid.sh (testet STDB-flyt)

Infrastruktur:
- Docker-container stoppet og fjernet fra docker-compose.yml
- Caddy: fjernet /spacetime/* reverse proxy
- maskinrommet-env.sh: fjernet STDB_IP og SPACETIMEDB_*-variabler
- .env.example: fjernet SpacetimeDB-seksjoner

Dokumentasjon oppdatert:
- CLAUDE.md: stack, lagmodell, kjerneprinsipper, driftsmodell
- docs/arkitektur.md: skrivestien, lesestien, datalag, teknologivalg
- docs/retninger/datalaget.md: migrasjonshistorikk, status "fjernet"
- 37 andre docs oppdatert (features, concepts, infra, ops, retninger)
- Alle kode-kommentarer med STDB-referanser oppdatert

Verifisert: maskinrommet bygger og starter OK, frontend bygger OK,
helsesjekk returnerer 200. Caddy reloadet.
2026-03-18 13:39:09 +00:00

11 KiB
Raw Blame History

Feature: AI-verktøy (Drag-and-drop tekstbehandling)

Filsti: docs/features/ai_verktoy.md

1. Konsept

Et frittstående verktøy-panel på arbeidsflaten for AI-drevet tekstbehandling. I stedet for en -knapp inne i editoren er AI-et et eget verktøy som lever side ved side med chat, artikkelverktøy, kanban og andre paneler. Brukeren konfigurerer verktøyet med en prompt og drar innhold til/fra det.

Inspirert av fysiske verktøy: du har en maskin på arbeidsbenken, konfigurert til å gjøre én ting godt. Du mater inn materiale, og får bearbeidet materiale tilbake. Maskinen står der klar mellom bruk.

2. Brukeropplevelse

2.1 Åpne og konfigurere

  1. Brukeren trekker AI-verktøyet inn på arbeidsflaten (fra verktøy-paletten).
  2. Verktøyet åpner seg med:
    • En prompt-velger med gjennomarbeidede standardprompter
    • Et fritekst-felt for egendefinert prompt
    • En modell-indikator (viser hvilken modell som brukes — styrt av server)
  3. Brukeren velger prompt og verktøyet er klart.
  4. Verktøyet husker konfigurasjonen — det står klart til bruk uten å rekonfigurere hver gang.

2.2 To retninger — to semantikker

Retning Metafor Handling Resultat
Verktøy → Node "Penselen" Dra AI-verktøyet og slipp på en tekstnode In-place revisjon: teksten modifiseres, originalen versjoneres
Node → Verktøy "Kverna" Dra en tekstnode og slipp på AI-verktøyet Ny node opprettes med derived_from-edge til kilden

Penselen — du bruker verktøyet teksten. Passer for korrektur, språkvask, rensing av innlimt rot. Teksten oppgraderes, originalen bevares som revisjon.

Kverna — du sender teksten gjennom verktøyet. Passer for oppsummering, oversettelse, uttrekk av fakta. Output er et nytt objekt som kan tas med videre til andre verktøy på flaten.

2.3 Typisk bruksscenario

Vegard sitter på bussen, leser en artikkel i VG på mobilen.
Ctrl+A → kopierer alt (artikkel + ingresser + annonser + navigasjon).
Limer inn i en ny node i Synops.

Drar AI-verktøyet (konfigurert med "Rens tekst") → noden.
AI-et vasker bort alt som ikke er artikkelen, strukturerer teksten,
forkorter, og oppgir kilde. Originalen er bevart som revisjon.

Ferdig. Ren, lesbar tekst. Ingen rot.

3. Standardprompter

Gjennomarbeidede, klare til bruk uten konfigurasjon:

Prompt Hva den gjør Typisk retning
Rens tekst Fjerner støy fra innlimt webinnhold, fikser skrivefeil, strukturerer, oppgir kilde Verktøy → Node
Korrektør Fikser grammatikk og skrivefeil, beholder innhold intakt Verktøy → Node
Oppsummering Kondenserer til 25 setninger med det viktigste Node → Verktøy
Oversett Oversetter til/fra norsk/engelsk Begge
Skriv om for publisering Omskriver til artikkelformat med tittel, ingress, brødtekst Node → Verktøy
Trekk ut fakta Identifiserer påstander, tall, sitater som separate punkter Node → Verktøy
Forenkle Omskriver til klarere, enklere språk Verktøy → Node
Endre tone Formell ↔ uformell, saklig ↔ engasjert Verktøy → Node

Brukere kan lage egne prompter og lagre dem. Egendefinerte prompter lagres som noder (node_kind: 'ai_preset') som kan deles via edges.

4. Modellstyring

Modell bestemmes av serveren, ikke brukeren.

Hvert AI-verktøy (standardprompt eller egendefinert) har en server-tildelt modellprofil. Brukeren ser hvilken modell som brukes (transparens), men kan ikke endre den.

Prompt-kategori Modellprofil Begrunnelse
Rens tekst, korrektør, forenkle Flash (billig, rask) Enkle transformasjoner
Oppsummering, oversettelse Flash (billig, rask) Rutineoppgaver
Skriv om for publisering Standard Krever mer resonering
Trekk ut fakta Standard Nøyaktighet viktigere
Egendefinert (default) Flash Kan oppgraderes av admin

Modellprofiler konfigureres i maskinrommet og mappes til LiteLLM-aliaser. Admin kan justere modellprofil per prompt via Prompt Lab.

Kostnadskontroll: Serveren styrer modellvalg for å hindre at brukere velger den dyreste modellen for alt. AI-forbruk logges per bruker/samling i ai_usage_log.

5. AI-verktøyet som node

AI-verktøyet er selv en node i grafen (node_kind: 'ai_preset'):

{
  "node_kind": "ai_preset",
  "title": "Rens tekst",
  "metadata": {
    "prompt": "Fiks denne teksten. Output på norsk...",
    "model_profile": "flash",
    "category": "standard",     // "standard" | "custom"
    "default_direction": "tool_to_node",  // hint for UI
    "icon": "sparkles",
    "color": "#8B5CF6"
  }
}

Fordeler:

  • Delbart: Edge til samling/team → alle i teamet har tilgang
  • Versjonerbart: Promptjustering over tid med revisjonshistorikk
  • Sporbart: derived_from-edge fra output til kilde + processed_by-edge til AI-preset → full provenance i kunnskapsgrafen
  • Gjenbrukbart: Flere instanser av samme verktøy med ulik konfigurasjon

6. Teknisk arkitektur

6.1 Signalflyt

Bruker drar node → AI-verktøy (eller omvendt)
  │
  ▼
Frontend sender intention til maskinrommet:
  POST /intentions/ai_process
  {
    source_node_id: "...",
    ai_preset_id: "...",
    direction: "node_to_tool" | "tool_to_node"
  }
  │
  ▼
Maskinrommet:
  1. Hent kilde-node content
  2. Hent AI-preset prompt + modellprofil
  3. Map modellprofil → LiteLLM-alias
  4. Send til AI Gateway (LiteLLM)
  5a. direction = tool_to_node:
      → Lagre original som revisjon
      → Oppdater node content med AI-output
  5b. direction = node_to_tool:
      → Opprett ny node med AI-output
      → Opprett derived_from-edge til kilde
      → Opprett processed_by-edge til AI-preset
  6. Logg forbruk i ai_usage_log
  │
  ▼
Frontend mottar oppdatering via WebSocket (PG LISTEN/NOTIFY)

6.2 Drag-and-drop integrasjon

AI-verktøyet følger arbeidsflate-konvensjonene fra docs/retninger/arbeidsflaten.md:

Som mål (node → verktøy):

  • Aksepterer: alle noder med content-felt (tekst, chatmeldinger, notater)
  • Drop-sone lyser opp med verktøyets farge under drag
  • Ved drop: opprett ny node, vis den ved siden av verktøyet

Som kilde (verktøy → node):

  • Verktøyet kan "dras" til en tekstnode
  • Drop-sone på tekstnoden lyser opp
  • Ved drop: modifiser noden in-place

Inkompatibilitet:

  • Lydfiler, bilder, mediefiler → "AI-verktøyet behandler kun tekst"
  • Tomme noder → "Noden har ikke innhold å behandle"

6.3 Oppdatering av kompatibilitetsmatrisen

Legges til i docs/retninger/arbeidsflaten.md:

Kilde → Mål AI-verktøy
Chatboble Ny node med AI-output + derived_from
Tekst/notat Ny node med AI-output + derived_from
Lydfil Inkompatibel: "AI-verktøyet behandler kun tekst"
Transkripsjon Ny node med AI-output + derived_from
Bilde Inkompatibel
Kilde → Mål Tekstnode (fra AI-verktøy)
AI-verktøy In-place revisjon av tekstnoden

7. Forhold til eksisterende AI-design

Erstatter -knappen i editoren

Editor-proposalen (docs/proposals/editor.md) beskriver en -knapp inne i editoren. Med spatial workspace-retningen erstattes denne av AI-verktøyet som eget panel. Fordeler:

  • Separat konfigurasjonsflate: Prompt og parametere lever i sitt eget panel, ikke gjemt bak en meny i editoren
  • Persistent: Verktøyet står konfigurert og klart. -knappen krever prompt-valg hver gang
  • Konsistent drag-and-drop: Samme interaksjonsmønster som mellom alle andre verktøy på flaten
  • Flere samtidige: Du kan ha "Rens tekst" og "Oppsummer" som to separate paneler, begge klare

Bygger på Prompt Lab

Egendefinerte prompter kan opprettes og testes i Prompt Lab (docs/features/prompt_lab.md) før de deployes som AI-preset-noder.

Fremtidig: kjeding

Flere AI-verktøy i serie: dra output fra "Oversett" videre til "Forenkle". Grafen sporer hele transformasjonskjeden via derived_from-edges. Ikke i scope for v1.

8. Avgrensning

  • Opererer på hele noden (hele content-feltet), ikke markert utvalg
  • Brukeren kan ikke velge modell — kun server-tildelt modellprofil
  • Ingen sanntids-streaming av AI-output (synkron respons via jobbkø)
  • Støtter kun tekst — ikke bilder, lyd eller video
  • Kjeding av verktøy er fremtidig funksjonalitet

9. Utviklingsfaser

Fase A: Grunnleggende verktøy-panel

  • AI-preset node-type (node_kind: 'ai_preset') + metadata-skjema
  • Standard-presets som seed-data (rens tekst, korrektør, oppsummering osv.)
  • POST /intentions/ai_process endepunkt i maskinrommet
  • Verktøy-panel UI med prompt-velger og modell-indikator
  • Jobbkø-integrasjon med AI Gateway

Fase B: Drag-and-drop

  • Node → verktøy: opprett ny node med derived_from-edge
  • Verktøy → node: in-place revisjon med versjonering
  • Drop-sone feedback (farge, inkompatibilitet)
  • Visuell output: ny node animeres inn ved siden av verktøyet

Fase C: Egendefinerte prompter

  • Opprett egne AI-preset-noder (POST /intentions/create_ai_preset)
  • Del via edges (samling/team) — shared_with-edge til samling
  • Rediger og slett egne presets (via update_node/delete_node)
  • Modellprofil-beskyttelse: kun admin kan endre model_profile
  • Prompt Lab-integrasjon for testing

10. Egendefinerte presets (oppgave 18.6)

10.1 Opprett egne AI-presets

Brukere kan opprette egne AI-preset-noder via POST /intentions/create_ai_preset:

{
  "title": "Lag ingress",
  "prompt": "Skriv en kort, fengende ingress for denne teksten...",
  "default_direction": "node_to_tool",
  "icon": "pencil_square",
  "color": "#10B981",
  "share_with_collection_id": "<uuid>"  // valgfri
}

Egendefinerte presets får alltid:

  • category: "custom" (kan ikke endres til "standard")
  • model_profile: "flash" (kan kun oppgraderes av admin)
  • visibility: "discoverable" (synlig for brukere med tilgang)

10.2 Deling via edges

Presets kan deles med samlinger/team via shared_with-edge:

  • Enten direkte i create_ai_preset via share_with_collection_id
  • Eller via create_edge med edge_type: "shared_with"

10.3 Modellprofil-beskyttelse

  • Vanlige brukere kan ikke endre model_profile — det er alltid "flash" for egne presets
  • Admin (owner/admin-edge til en samling) kan oppgradere til "standard" via update_node
  • Kategori "standard" er reservert for systempresets og kan ikke velges av brukere

10.4 Frontend

AiToolPanel har:

  • "+ Nytt preset"-knapp for å opprette egne presets
  • Rediger/slett/del-knapper for egne custom presets
  • Egendefinerte presets markert med "egn." i preset-velgeren
  • Delingsdialog for å dele med samling via UUID

11. Instruks for Claude Code

  • AI-behandling skjer alltid via maskinrommet, aldri direkte fra frontend
  • Modellprofil → LiteLLM-alias-mapping konfigureres i maskinrommet
  • Brukeren kan ikke velge modell — dette er en server-side beslutning
  • Standardprompter er seed-data som opprettes ved deploy, ikke hardkodet i frontend
  • derived_from-edge og processed_by-edge gir sporbarhet i grafen
  • AI-forbruk logges alltid i ai_usage_log per bruker, samling og preset
  • Hele noden prosesseres — ingen "markert utvalg"-støtte