diff --git a/docs/concepts/orkestrering.md b/docs/concepts/orkestrering.md new file mode 100644 index 0000000..fc29410 --- /dev/null +++ b/docs/concepts/orkestrering.md @@ -0,0 +1,241 @@ +# Konsept: Orkestrering +**Filsti:** `docs/concepts/orkestrering.md` + +## 1. Konsept + +Orkestreringer er noder som *gjør* ting. De er oppskrifter — +sekvenser av CLI-verktøy og bot-instruksjoner som utføres +automatisk når en trigger aktiveres. Brukeren skriver hva som +skal skje i naturlig språk. Boten tolker og utfører. + +## 2. Hvorfor + +Synops har mange automatiseringer hardkodet i portvokteren: +podcast-pipeline, AI-beriking, publisering. De er usynlige, +uendrelige og umulige å tilpasse for brukere. + +Orkestreringer gjør automatisering til førsteklasses graf- +primitiver — synlige, redigerbare, delbare, versjonerbare. + +## 3. Nodemodell + +``` +node_kind: 'orchestration' +title: "Podcast: opptak → publisering" +content: "Når en innspilling avsluttes..." +metadata: { + "trigger": { + "event": "communication.ended", + "conditions": { + "has_trait": "podcast", + "has_media": "audio" + } + }, + "executor": "bot", + "intelligence": 2, + "effort": 2, + "compiled": false +} +``` + +### Tre typer noder som gjør + +| node_kind | Ikon | Aktivering | Eksempel | +|-----------|------|------------|----------| +| `cli_tool` | 🔧 | Kalles av andre | synops-transcribe | +| `ai_preset` | 🔧 | Kalles av AI-verktøy | "Rens tekst"-prompt | +| `orchestration` | ⚡ | **Trigger-drevet, utfører seg selv** | Podcast-pipeline | + +⚡ signaliserer: "denne noden gjør noe av seg selv." + +## 4. Fritekst-instruksjoner + +Stegene i en orkestrering er naturlig språk: + +``` +Når en innspilling i en samling med podcast-trait avsluttes: + +1. Transkriber lydfilen med synops-transcribe (model: large) +2. Generer oppsummering med synops-summarize +3. Foreslå kapitler basert på transkripsjonen +4. Generer show notes +5. Oppdater RSS-feed med synops-rss + +Hvis transkribering feiler, prøv igjen med model: medium. +Hvis RSS feiler, opprett work_item med tag 'bug'. +``` + +Brukeren skriver hva de vil. Boten tolker instruksjonene og +utfører med function calling — kaller CLI-verktøy via +portvokteren (se `docs/infra/robusthet.md` § function calling). + +### Hvorfor fritekst, ikke DSL? + +- Ingen DSL å lære for brukeren +- Boten resonnerer om feil og edge cases +- Feilhåndtering er naturlig ("hvis X feiler, prøv Y") +- Endring er å redigere tekst, ikke debugge JSON + +## 5. Strukturert trigger + +Triggeren er den eneste strukturerte delen — portvokteren +evaluerer den effektivt uten LLM: + +```jsonc +{ + "trigger": { + "event": "communication.ended", + "conditions": { + "has_trait": "podcast", + "has_media": "audio" + } + } +} +``` + +### Kjente trigger-events + +| Event | Beskrivelse | +|-------|-------------| +| `node.created` | Ny node opprettet | +| `edge.created` | Ny edge opprettet | +| `communication.ended` | Samtale/innspilling avsluttet | +| `node.published` | Node publisert (belongs_to med slot) | +| `scheduled.due` | Planlagt tidspunkt nådd | +| `manual` | Bruker trykker "Kjør" | + +### Betingelser + +Filtrerer triggeren ytterligere: +- `has_trait` — noden/samlingen har denne traiten +- `has_media` — noden har media-edge av denne typen +- `has_tag` — noden har tagged-edge med denne verdien +- `node_kind` — noden er av denne typen + +## 6. Utførelse + +### Bot-modus (default) + +``` +Trigger aktiveres + → Portvokteren finner matchende orchestration-node + → Sender til bot med function calling: + - Trigger-kontekst (hvilken node, hvilken event) + - Instruksjonene fra orchestration.content + - Tilgjengelige verktøy (cli_tool-noder) + → Boten utfører steg for steg + → Logger hvert steg i orchestration_log + → Ved feil: resonnerer og prøver alternativ +``` + +### Kompilert modus (optimalisert) + +Når en orkestrering har kjørt mange ganger med samme mønster, +kan den kompileres til en direkte pipeline: + +```jsonc +{ + "compiled": true, + "pipeline": [ + { "tool": "synops-transcribe", "args_map": {"cas_hash": "input.cas_hash", "model": "large"} }, + { "tool": "synops-summarize", "args_map": {"communication_id": "input.id"} }, + { "tool": "synops-rss", "args_map": {"collection_id": "input.collection_id"} } + ], + "fallback": "bot" +} +``` + +Ingen LLM-kall for standardsteg. Direkte dispatch. Mye raskere, +billigere, deterministisk. `fallback: "bot"` betyr: ved feil +eller uventet situasjon, fall tilbake til fritekst-instruksjonene. + +### Naturlig progresjon + +``` +1. Fritekst → Brukere skriver, boten tolker +2. Observér → Boten logger hvilke verktøy/sekvenser som gjentas +3. Foreslå → "Denne har kjørt 50 ganger. Kompilere?" +4. Kompilér → Fast pipeline, ingen LLM for standardsteg +5. DSL (senere) → Kun hvis kompilerte pipelines trenger mer uttrykk +``` + +DSL-en designes ikke nå — den oppstår fra observerte mønstre. + +## 7. Koblinger mellom orkestreringer + +Orkestreringer er noder med edges: + +``` +"Podcast: opptak → publisering" + ──triggers──→ "Varsle redaksjonen om ny episode" + ──triggers──→ "Post til sosiale medier" +``` + +Output fra én orkestrering kan trigge neste via `triggers`-edge. +Kaskade via edges, ikke hardkodet. + +## 8. Brukergrensesnitt + +``` +┌─ Podcastorkestrering ⚡ ──────────────────┐ +│ │ +│ Trigger: [Innspilling avsluttet ▼] │ +│ Betingelse: [Samling har podcast-trait ▼] │ +│ │ +│ Steg: │ +│ ┌─────────────────────────────────────┐ │ +│ │ Transkriber lydfilen med stor │ │ +│ │ modell. Hvis det feiler, bruk │ │ +│ │ medium. │ │ +│ ├─────────────────────────────────────┤ │ +│ │ Oppsummer samtalen. │ │ +│ ├─────────────────────────────────────┤ │ +│ │ Foreslå kapitler. │ │ +│ ├─────────────────────────────────────┤ │ +│ │ Oppdater RSS-feed. │ │ +│ └─────────────────────────────────────┘ │ +│ │ +│ [+ Legg til steg] [▶ Test kjøring] │ +│ │ +│ Status: Aktiv Kjørt: 47 ganger │ +│ Sist: 2026-03-18 12:30 (OK) │ +└───────────────────────────────────────────┘ +``` + +Hvert steg er en tekstboks. "Test kjøring" sender til boten +med dry-run. Historikk synlig. + +## 9. Edge-modell + +| Edge | Source → Target | Betydning | +|------|----------------|-----------| +| `belongs_to` | orchestration → collection | Tilhører denne samlingen | +| `triggers` | orchestration → orchestration | Kaskade-kobling | +| `uses` | orchestration → cli_tool | Bruker dette verktøyet | +| `mentions` | orchestration → any | Refererer til denne noden | + +## 10. Avgrensning + +- Orkestreringer er **ikke** en generell workflow-engine. + De er oppskrifter som boten følger. +- Fritekst-instruksjoner er primær. Kompilering er + optimalisering, ikke krav. +- Triggere evalueres av portvokteren, utførelse av boten. + Klar ansvarsfordeling. +- Feilhåndtering er botens ansvar. Ingen retry-DSL. + +## 11. Komponenter + +| Feature | Rolle | +|---------|-------| +| Portvokteren | Evaluerer triggere, dispatcher til bot | +| @bot | Tolker instruksjoner, utfører med function calling | +| CLI-verktøy | Gjør det faktiske arbeidet | +| Arbeidstavlen | Work items opprettes ved feil | +| Responskvalitet | Intelligence/effort per orkestrering | + +## 12. Bygger på +- `docs/retninger/unix_filosofi.md` — CLI-verktøy som byggeklosser +- `docs/concepts/arbeidstavlen.md` — @bot, work items ved feil +- `docs/infra/robusthet.md` — function calling, fallback +- `docs/features/responskvalitet.md` — intelligence/effort-nivåer diff --git a/docs/primitiver/nodes.md b/docs/primitiver/nodes.md index 7ce45ef..8e143d0 100644 --- a/docs/primitiver/nodes.md +++ b/docs/primitiver/nodes.md @@ -54,6 +54,7 @@ Kjente node_kinds: | `workspace` | Personlig arbeidsflate (én per bruker, auto-provisjonert) | | `work_item` | Oppgave, bug, idé, forslag (se `docs/concepts/arbeidstavlen.md`) | | `cli_tool` | CLI-verktøy med spec, bruk og metadata (se `docs/retninger/unix_filosofi.md`) | +| `orchestration` | Automatisert oppskrift med trigger og steg (se `docs/concepts/orkestrering.md`) | Listen vokser organisk etter behov.