Spesifiser orkestrering: trigger-drevne noder som utfører seg selv

Nytt konseptdokument for orchestration-noder ():
- Fritekst-instruksjoner som boten tolker og utfører
- Strukturerte triggere (portvokteren evaluerer uten LLM)
- Naturlig progresjon: fritekst → observér → kompilér → DSL
- Kompilerte pipelines med bot-fallback ved feil
- Kaskade mellom orkestreringer via triggers-edges
- Visuell editor med tekstbokser per steg og test-kjøring

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
vegard 2026-03-18 13:17:53 +00:00
parent b1ba06cd21
commit 79acf0bb0a
2 changed files with 242 additions and 0 deletions

View file

@ -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

View file

@ -54,6 +54,7 @@ Kjente node_kinds:
| `workspace` | Personlig arbeidsflate (én per bruker, auto-provisjonert) | | `workspace` | Personlig arbeidsflate (én per bruker, auto-provisjonert) |
| `work_item` | Oppgave, bug, idé, forslag (se `docs/concepts/arbeidstavlen.md`) | | `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`) | | `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. Listen vokser organisk etter behov.