Orkestrering: tre nivåer (script/fritekst/drøm) + rename portvokter→vaktmester
Orkestrering restrukturert med deklarativt script som primærnivå:
- Nivå 1: eksakte CLI-kall med {event.*}-variabler, ingen AI
- Nivå 2: fritekst tolket av bot med function calling
- Nivå 3: drømmemodus — bruker skriver fritt, mangler→work_items
- Auto-eskalering: script→bot ved uventet feil
Rename portvokter→vaktmester i alle docs — bedre navn for en
tjeneste som gjør ting, ikke bare sjekker legitimasjon.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
68f7b10e9b
commit
fd0b75ee13
7 changed files with 188 additions and 144 deletions
|
|
@ -182,7 +182,7 @@ Kanal 2 er usynlig for brukeren. De ser bare svaret.
|
||||||
|
|
||||||
1. En bruker skriver i en kommunikasjonsnode der bot-agenten er
|
1. En bruker skriver i en kommunikasjonsnode der bot-agenten er
|
||||||
`member_of`.
|
`member_of`.
|
||||||
2. Portvokteren trigger `agent_respond`-jobb (eksisterende flow).
|
2. Vaktmesteren trigger `agent_respond`-jobb (eksisterende flow).
|
||||||
3. Boten svarer i samtalen.
|
3. Boten svarer i samtalen.
|
||||||
4. Boten vurderer: er noe her actionable?
|
4. Boten vurderer: er noe her actionable?
|
||||||
5. Hvis ja: oppretter riktig node-type med riktig tag.
|
5. Hvis ja: oppretter riktig node-type med riktig tag.
|
||||||
|
|
@ -213,7 +213,7 @@ Vegard triagerer innboksen og prioriterer.
|
||||||
|
|
||||||
### Ruting
|
### Ruting
|
||||||
|
|
||||||
`@bot` rutes av portvokteren basert på kontekst:
|
`@bot` rutes av vaktmesteren basert på kontekst:
|
||||||
- Standard: Claude (nåværende `agent_respond`-flyt)
|
- Standard: Claude (nåværende `agent_respond`-flyt)
|
||||||
- Fremtidig: spesialiserte agenter, andre modeller, eller
|
- Fremtidig: spesialiserte agenter, andre modeller, eller
|
||||||
regelbaserte svar — uten endring i brukergrensesnittet
|
regelbaserte svar — uten endring i brukergrensesnittet
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,13 @@
|
||||||
## 1. Konsept
|
## 1. Konsept
|
||||||
|
|
||||||
Orkestreringer er noder som *gjør* ting. De er oppskrifter —
|
Orkestreringer er noder som *gjør* ting. De er oppskrifter —
|
||||||
sekvenser av CLI-verktøy og bot-instruksjoner som utføres
|
sekvenser av CLI-verktøy som utføres automatisk når en trigger
|
||||||
automatisk når en trigger aktiveres. Brukeren skriver hva som
|
aktiveres. Tre nivåer: deklarativt script (ingen AI),
|
||||||
skal skje i naturlig språk. Boten tolker og utfører.
|
fritekst med AI-tolkning, og full drømmemodus.
|
||||||
|
|
||||||
## 2. Hvorfor
|
## 2. Hvorfor
|
||||||
|
|
||||||
Synops har mange automatiseringer hardkodet i portvokteren:
|
Synops har mange automatiseringer hardkodet i vaktmesteren:
|
||||||
podcast-pipeline, AI-beriking, publisering. De er usynlige,
|
podcast-pipeline, AI-beriking, publisering. De er usynlige,
|
||||||
uendrelige og umulige å tilpasse for brukere.
|
uendrelige og umulige å tilpasse for brukere.
|
||||||
|
|
||||||
|
|
@ -22,7 +22,7 @@ primitiver — synlige, redigerbare, delbare, versjonerbare.
|
||||||
```
|
```
|
||||||
node_kind: 'orchestration'
|
node_kind: 'orchestration'
|
||||||
title: "Podcast: opptak → publisering"
|
title: "Podcast: opptak → publisering"
|
||||||
content: "Når en innspilling avsluttes..."
|
content: <script eller fritekst>
|
||||||
metadata: {
|
metadata: {
|
||||||
"trigger": {
|
"trigger": {
|
||||||
"event": "communication.ended",
|
"event": "communication.ended",
|
||||||
|
|
@ -31,10 +31,9 @@ metadata: {
|
||||||
"has_media": "audio"
|
"has_media": "audio"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"executor": "bot",
|
"executor": "script" | "bot" | "dream",
|
||||||
"intelligence": 2,
|
"intelligence": 2,
|
||||||
"effort": 2,
|
"effort": 2
|
||||||
"compiled": false
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -48,38 +47,95 @@ metadata: {
|
||||||
|
|
||||||
⚡ signaliserer: "denne noden gjør noe av seg selv."
|
⚡ signaliserer: "denne noden gjør noe av seg selv."
|
||||||
|
|
||||||
## 4. Fritekst-instruksjoner
|
## 4. Tre utførelsesnivåer
|
||||||
|
|
||||||
Stegene i en orkestrering er naturlig språk:
|
### Nivå 1: Deklarativt script (ingen AI)
|
||||||
|
|
||||||
|
Eksakte CLI-kall med variabler fra trigger-konteksten.
|
||||||
|
Vaktmesteren parser og eksekverer direkte — ingen LLM.
|
||||||
|
|
||||||
|
```
|
||||||
|
NÅR innspilling.avsluttet
|
||||||
|
HVIS samling.har_trait("podcast")
|
||||||
|
|
||||||
|
1. synops-transcribe --cas-hash {event.cas_hash} --model large
|
||||||
|
VED_FEIL: synops-transcribe --cas-hash {event.cas_hash} --model medium
|
||||||
|
2. synops-summarize --communication-id {event.communication_id}
|
||||||
|
3. synops-rss --collection-id {event.collection_id}
|
||||||
|
|
||||||
|
VED_FEIL: work_item "Podcast-pipeline feilet" --tag bug
|
||||||
|
```
|
||||||
|
|
||||||
|
**Grammatikk:**
|
||||||
|
|
||||||
|
```
|
||||||
|
TRIGGER NÅR <event> [HVIS <betingelse>]
|
||||||
|
STEP <N>. <tool> <args...>
|
||||||
|
FALLBACK VED_FEIL: <tool> <args...> | work_item <title> [--tag <tag>]
|
||||||
|
VARIABLE {event.<felt>} — substitueres fra trigger-konteksten
|
||||||
|
```
|
||||||
|
|
||||||
|
Enkelt nok til å parse med en liten Rust-parser i vaktmesteren.
|
||||||
|
Deterministisk, gratis, raskt. **De fleste produksjons-
|
||||||
|
orkestreringer vil være på dette nivået.**
|
||||||
|
|
||||||
|
### Nivå 2: Fritekst med AI-tolkning
|
||||||
|
|
||||||
|
Naturlig språk som boten tolker og utfører steg for steg
|
||||||
|
med function calling. For orkestreringer der stegene ikke
|
||||||
|
er helt forutsigbare.
|
||||||
|
|
||||||
```
|
```
|
||||||
Når en innspilling i en samling med podcast-trait avsluttes:
|
Når en innspilling i en samling med podcast-trait avsluttes:
|
||||||
|
|
||||||
1. Transkriber lydfilen med synops-transcribe (model: large)
|
1. Transkriber lydfilen med stor modell
|
||||||
2. Generer oppsummering med synops-summarize
|
2. Generer oppsummering
|
||||||
3. Foreslå kapitler basert på transkripsjonen
|
3. Foreslå kapitler basert på transkripsjonen
|
||||||
4. Generer show notes
|
4. Generer show notes
|
||||||
5. Oppdater RSS-feed med synops-rss
|
5. Oppdater RSS-feed
|
||||||
|
|
||||||
Hvis transkribering feiler, prøv igjen med model: medium.
|
Hvis transkribering feiler, prøv igjen med medium modell.
|
||||||
Hvis RSS feiler, opprett work_item med tag 'bug'.
|
Hvis RSS feiler, opprett en oppgave.
|
||||||
```
|
```
|
||||||
|
|
||||||
Brukeren skriver hva de vil. Boten tolker instruksjonene og
|
Boten mapper "transkriber lydfilen" → `synops-transcribe`,
|
||||||
utfører med function calling — kaller CLI-verktøy via
|
"oppsummer" → `synops-summarize`, osv. Krever LLM-kall
|
||||||
portvokteren (se `docs/infra/robusthet.md` § function calling).
|
per kjøring (Haiku er nok for de fleste).
|
||||||
|
|
||||||
### Hvorfor fritekst, ikke DSL?
|
### Nivå 3: Drømmemodus
|
||||||
|
|
||||||
- Ingen DSL å lære for brukeren
|
Brukeren skriver hva de *ønsker*, uten å vite hvilke verktøy
|
||||||
- Boten resonnerer om feil og edge cases
|
som finnes. Boten prøver, og mangler som oppdages blir
|
||||||
- Feilhåndtering er naturlig ("hvis X feiler, prøv Y")
|
feature requests.
|
||||||
- Endring er å redigere tekst, ikke debugge JSON
|
|
||||||
|
```
|
||||||
|
Gjør episoden klar for publisering. Lag en lydfil med
|
||||||
|
sammendrag og send den til alle deltakere.
|
||||||
|
```
|
||||||
|
|
||||||
|
Boten sjekker tilgjengelige verktøy, gjør det den kan,
|
||||||
|
og oppretter work_items for det som mangler.
|
||||||
|
|
||||||
|
### Naturlig progresjon
|
||||||
|
|
||||||
|
```
|
||||||
|
Drømmemodus → Bruker beskriver ønsket resultat
|
||||||
|
↓ AI foreslår
|
||||||
|
Fritekst → Bruker justerer steg i naturlig språk
|
||||||
|
↓ AI foreslår kompilering etter N kjøringer
|
||||||
|
Script → Deklarative CLI-kall, ingen AI
|
||||||
|
↓ manuelt
|
||||||
|
Kode → Eget CLI-verktøy (synops-<verb>)
|
||||||
|
```
|
||||||
|
|
||||||
|
Hvert nivå kan fryses til nivået under. AI foreslår
|
||||||
|
kompilering, bruker godkjenner. Scriptet kan alltid
|
||||||
|
redigeres manuelt.
|
||||||
|
|
||||||
## 5. Strukturert trigger
|
## 5. Strukturert trigger
|
||||||
|
|
||||||
Triggeren er den eneste strukturerte delen — portvokteren
|
Triggeren er alltid strukturert — vaktmesteren evaluerer
|
||||||
evaluerer den effektivt uten LLM:
|
den effektivt uten LLM, uavhengig av utførelsesnivå:
|
||||||
|
|
||||||
```jsonc
|
```jsonc
|
||||||
{
|
{
|
||||||
|
|
@ -114,11 +170,26 @@ Filtrerer triggeren ytterligere:
|
||||||
|
|
||||||
## 6. Utførelse
|
## 6. Utførelse
|
||||||
|
|
||||||
### Bot-modus (default)
|
### Script-modus (nivå 1)
|
||||||
|
|
||||||
```
|
```
|
||||||
Trigger aktiveres
|
Trigger aktiveres
|
||||||
→ Portvokteren finner matchende orchestration-node
|
→ Vaktmesteren finner matchende orchestration-node
|
||||||
|
→ Parser scriptet
|
||||||
|
→ Substituerer {event.*}-variabler fra trigger-kontekst
|
||||||
|
→ Utfører steg sekvensielt via generisk dispatch
|
||||||
|
(synops-{tool} --payload-json)
|
||||||
|
→ Ved feil: kjør VED_FEIL-steg eller opprett work_item
|
||||||
|
→ Logger i orchestration_log
|
||||||
|
```
|
||||||
|
|
||||||
|
Ingen LLM. Deterministisk. Raskt.
|
||||||
|
|
||||||
|
### Bot-modus (nivå 2)
|
||||||
|
|
||||||
|
```
|
||||||
|
Trigger aktiveres
|
||||||
|
→ Vaktmesteren finner matchende orchestration-node
|
||||||
→ Sender til bot med function calling:
|
→ Sender til bot med function calling:
|
||||||
- Trigger-kontekst (hvilken node, hvilken event)
|
- Trigger-kontekst (hvilken node, hvilken event)
|
||||||
- Instruksjonene fra orchestration.content
|
- Instruksjonene fra orchestration.content
|
||||||
|
|
@ -128,39 +199,24 @@ Trigger aktiveres
|
||||||
→ Ved feil: resonnerer og prøver alternativ
|
→ Ved feil: resonnerer og prøver alternativ
|
||||||
```
|
```
|
||||||
|
|
||||||
### Kompilert modus (optimalisert)
|
### Drømmemodus (nivå 3)
|
||||||
|
|
||||||
Når en orkestrering har kjørt mange ganger med samme mønster,
|
Som bot-modus, men med høyere intelligens (Sonnet+) og
|
||||||
kan den kompileres til en direkte pipeline:
|
instruks om å opprette work_items for manglende verktøy.
|
||||||
|
|
||||||
```jsonc
|
### Auto-eskalering
|
||||||
{
|
|
||||||
"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,
|
Script-modus faller tilbake til bot-modus ved uventet feil:
|
||||||
billigere, deterministisk. `fallback: "bot"` betyr: ved feil
|
|
||||||
eller uventet situasjon, fall tilbake til fritekst-instruksjonene.
|
|
||||||
|
|
||||||
### Naturlig progresjon
|
|
||||||
|
|
||||||
```
|
```
|
||||||
1. Fritekst → Brukere skriver, boten tolker
|
Script kjører steg 2
|
||||||
2. Observér → Boten logger hvilke verktøy/sekvenser som gjentas
|
→ synops-summarize returnerer exit 1
|
||||||
3. Foreslå → "Denne har kjørt 50 ganger. Kompilere?"
|
→ VED_FEIL er definert → prøv alternativ
|
||||||
4. Kompilér → Fast pipeline, ingen LLM for standardsteg
|
→ Alternativ feiler også
|
||||||
5. DSL (senere) → Kun hvis kompilerte pipelines trenger mer uttrykk
|
→ Eskalér til bot-modus for dette steget
|
||||||
|
→ Boten resonnerer om feilen og prøver å løse det
|
||||||
```
|
```
|
||||||
|
|
||||||
DSL-en designes ikke nå — den oppstår fra observerte mønstre.
|
|
||||||
|
|
||||||
## 7. Koblinger mellom orkestreringer
|
## 7. Koblinger mellom orkestreringer
|
||||||
|
|
||||||
Orkestreringer er noder med edges:
|
Orkestreringer er noder med edges:
|
||||||
|
|
@ -181,29 +237,36 @@ Kaskade via edges, ikke hardkodet.
|
||||||
│ │
|
│ │
|
||||||
│ Trigger: [Innspilling avsluttet ▼] │
|
│ Trigger: [Innspilling avsluttet ▼] │
|
||||||
│ Betingelse: [Samling har podcast-trait ▼] │
|
│ Betingelse: [Samling har podcast-trait ▼] │
|
||||||
|
│ Modus: [Script ▼] │
|
||||||
│ │
|
│ │
|
||||||
│ Steg: │
|
|
||||||
│ ┌─────────────────────────────────────┐ │
|
│ ┌─────────────────────────────────────┐ │
|
||||||
│ │ Transkriber lydfilen med stor │ │
|
│ │ NÅR innspilling.avsluttet │ │
|
||||||
│ │ modell. Hvis det feiler, bruk │ │
|
│ │ HVIS samling.har_trait("podcast") │ │
|
||||||
│ │ medium. │ │
|
│ │ │ │
|
||||||
│ ├─────────────────────────────────────┤ │
|
│ │ 1. synops-transcribe │ │
|
||||||
│ │ Oppsummer samtalen. │ │
|
│ │ --cas-hash {event.cas_hash} │ │
|
||||||
│ ├─────────────────────────────────────┤ │
|
│ │ --model large │ │
|
||||||
│ │ Foreslå kapitler. │ │
|
│ │ VED_FEIL: ... --model medium │ │
|
||||||
│ ├─────────────────────────────────────┤ │
|
│ │ 2. synops-summarize │ │
|
||||||
│ │ Oppdater RSS-feed. │ │
|
│ │ --communication-id {event.id} │ │
|
||||||
|
│ │ 3. synops-rss │ │
|
||||||
|
│ │ --collection-id {event.coll_id} │ │
|
||||||
│ └─────────────────────────────────────┘ │
|
│ └─────────────────────────────────────┘ │
|
||||||
│ │
|
│ │
|
||||||
│ [+ Legg til steg] [▶ Test kjøring] │
|
│ [▶ Test kjøring] [↑ Konverter til AI] │
|
||||||
│ │
|
│ │
|
||||||
│ Status: Aktiv Kjørt: 47 ganger │
|
│ Status: Aktiv Kjørt: 47 ganger │
|
||||||
│ Sist: 2026-03-18 12:30 (OK) │
|
│ Sist: 2026-03-18 12:30 (OK) │
|
||||||
|
│ │
|
||||||
|
│ ℹ Tilgjengelig: synops-transcribe, │
|
||||||
|
│ synops-rss, synops-render... │
|
||||||
|
│ (12 verktøy) │
|
||||||
└───────────────────────────────────────────┘
|
└───────────────────────────────────────────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
Hvert steg er en tekstboks. "Test kjøring" sender til boten
|
Modusvelger: Script / Fritekst / Drømmemodus.
|
||||||
med dry-run. Historikk synlig.
|
"Test kjøring" utfører med dry-run.
|
||||||
|
"Konverter til AI" løfter scriptet til fritekst-modus.
|
||||||
|
|
||||||
## 9. Edge-modell
|
## 9. Edge-modell
|
||||||
|
|
||||||
|
|
@ -226,12 +289,13 @@ Orkestreringen peker på det den observerer:
|
||||||
```
|
```
|
||||||
|
|
||||||
Legg til `observes`-edge → aktivert for den noden.
|
Legg til `observes`-edge → aktivert for den noden.
|
||||||
Fjern edge → deaktivert. Samme orkestrering kan observere mange noder.
|
Fjern edge → deaktivert. Opprettet via drag-and-drop
|
||||||
|
(se `docs/retninger/interaksjonsmodell.md`).
|
||||||
|
|
||||||
### Implisitt vs eksplisitt
|
### Implisitt vs eksplisitt
|
||||||
|
|
||||||
- **`observes`-edge:** Eksplisitt. "Denne orkestreringen overvåker
|
- **`observes`-edge:** Eksplisitt. "Denne orkestreringen overvåker
|
||||||
denne noden." Opprettet via drag-and-drop (se § interaksjonsmodell).
|
denne noden."
|
||||||
- **Trigger-betingelser:** Implisitt. "Overvåk alt som matcher."
|
- **Trigger-betingelser:** Implisitt. "Overvåk alt som matcher."
|
||||||
- `observes` overtrumfer: fjernet `observes`-edge betyr "ikke her",
|
- `observes` overtrumfer: fjernet `observes`-edge betyr "ikke her",
|
||||||
selv om betingelsene matcher. Brukeren har kontroll.
|
selv om betingelsene matcher. Brukeren har kontroll.
|
||||||
|
|
@ -241,8 +305,6 @@ Fjern edge → deaktivert. Samme orkestrering kan observere mange noder.
|
||||||
Brukeren begrenses ikke til kjente verktøy. De skriver fritt
|
Brukeren begrenses ikke til kjente verktøy. De skriver fritt
|
||||||
— boten prøver, og mangler som oppdages blir feature requests.
|
— boten prøver, og mangler som oppdages blir feature requests.
|
||||||
|
|
||||||
### Slik fungerer det
|
|
||||||
|
|
||||||
```
|
```
|
||||||
Bruker skriver: "Lag en lydfil med sammendrag og send til deltakerne"
|
Bruker skriver: "Lag en lydfil med sammendrag og send til deltakerne"
|
||||||
|
|
||||||
|
|
@ -250,7 +312,7 @@ Boten sjekker:
|
||||||
✓ synops-summarize finnes → oppsummerer
|
✓ synops-summarize finnes → oppsummerer
|
||||||
✗ synops-tts finnes ikke → kan ikke lage lyd
|
✗ synops-tts finnes ikke → kan ikke lage lyd
|
||||||
|
|
||||||
Boten svarer i chatten:
|
Boten svarer:
|
||||||
"Jeg oppsummerte møtet, men Synops har ikke tekst-til-tale
|
"Jeg oppsummerte møtet, men Synops har ikke tekst-til-tale
|
||||||
ennå. Jeg oppretter en forespørsel?"
|
ennå. Jeg oppretter en forespørsel?"
|
||||||
|
|
||||||
|
|
@ -260,50 +322,32 @@ Boten svarer i chatten:
|
||||||
source_material → orkestreringsnoden
|
source_material → orkestreringsnoden
|
||||||
```
|
```
|
||||||
|
|
||||||
Hver feilet steg som skyldes manglende verktøy er en **feature
|
Systemet lærer hva brukerne vil ha fra det som ikke lykkes.
|
||||||
request** — gratis, kontekstuell, fra faktisk behov. Systemet
|
|
||||||
lærer hva brukerne vil ha fra orkestreringer som ikke lykkes.
|
|
||||||
|
|
||||||
### Diskret hint, ikke begrensning
|
|
||||||
|
|
||||||
I editoren vises tilgjengelige verktøy som hint, men brukeren
|
|
||||||
kan skrive hva som helst:
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─ Steg 3 ──────────────────────────────────┐
|
|
||||||
│ Lag en lydfil med oppsummeringen og send │
|
|
||||||
│ den til alle deltakere │
|
|
||||||
│ │
|
|
||||||
│ ℹ Tilgjengelig: synops-tts, synops-rss, │
|
|
||||||
│ synops-render, synops-transcribe... │
|
|
||||||
│ (12 verktøy) — men skriv hva du vil │
|
|
||||||
└────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
Brukeren drømmer. Systemet vokser.
|
|
||||||
|
|
||||||
## 11. Avgrensning
|
## 11. Avgrensning
|
||||||
|
|
||||||
- Orkestreringer er **ikke** en generell workflow-engine.
|
- Orkestreringer er **ikke** en generell workflow-engine.
|
||||||
De er oppskrifter som boten følger.
|
De er oppskrifter — deklarative eller AI-tolkede.
|
||||||
- Fritekst-instruksjoner er primær. Kompilering er
|
- Deklarativt script er primær for produksjon. AI er for
|
||||||
optimalisering, ikke krav.
|
oppretting, feilhåndtering og drømmemodus.
|
||||||
- Triggere evalueres av portvokteren, utførelse av boten.
|
- Triggere evalueres av vaktmesteren, utførelse av
|
||||||
Klar ansvarsfordeling.
|
vaktmesteren (script) eller bot (fritekst/drøm).
|
||||||
- Feilhåndtering er botens ansvar. Ingen retry-DSL.
|
- Brukeren begrenses aldri til kjente verktøy. Manglende
|
||||||
|
funksjonalitet fanges opp som feature requests.
|
||||||
|
|
||||||
## 12. Komponenter
|
## 12. Komponenter
|
||||||
|
|
||||||
| Feature | Rolle |
|
| Feature | Rolle |
|
||||||
|---------|-------|
|
|---------|-------|
|
||||||
| Portvokteren | Evaluerer triggere, dispatcher til bot |
|
| Vaktmesteren | Evaluerer triggere, parser/utfører scripts, dispatcher til bot |
|
||||||
| @bot | Tolker instruksjoner, utfører med function calling |
|
| @bot | Tolker fritekst-instruksjoner, utfører med function calling |
|
||||||
| CLI-verktøy | Gjør det faktiske arbeidet |
|
| CLI-verktøy | Gjør det faktiske arbeidet |
|
||||||
| Arbeidstavlen | Work items opprettes ved feil |
|
| Arbeidstavlen | Work items opprettes ved feil |
|
||||||
| Responskvalitet | Intelligence/effort per orkestrering |
|
| Responskvalitet | Intelligence/effort per orkestrering |
|
||||||
|
|
||||||
## 13. Bygger på
|
## 13. Bygger på
|
||||||
- `docs/retninger/unix_filosofi.md` — CLI-verktøy som byggeklosser
|
- `docs/retninger/unix_filosofi.md` — CLI-verktøy som byggeklosser
|
||||||
|
- `docs/retninger/interaksjonsmodell.md` — drag-and-drop for observes-edge
|
||||||
- `docs/concepts/arbeidstavlen.md` — @bot, work items ved feil
|
- `docs/concepts/arbeidstavlen.md` — @bot, work items ved feil
|
||||||
- `docs/infra/robusthet.md` — function calling, fallback
|
- `docs/infra/robusthet.md` — function calling, fallback
|
||||||
- `docs/features/responskvalitet.md` — intelligence/effort-nivåer
|
- `docs/features/responskvalitet.md` — intelligence/effort-nivåer
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ For hver tjeneste:
|
||||||
- Avhengigheter
|
- Avhengigheter
|
||||||
- Healthcheck
|
- Healthcheck
|
||||||
|
|
||||||
Tjenester: Caddy, portvokteren, SvelteKit, PostgreSQL,
|
Tjenester: Caddy, vaktmesteren, SvelteKit, PostgreSQL,
|
||||||
Authentik, LiteLLM, faster-whisper, LiveKit.
|
Authentik, LiteLLM, faster-whisper, LiveKit.
|
||||||
|
|
||||||
### 4. CLI-verktøy
|
### 4. CLI-verktøy
|
||||||
|
|
@ -77,7 +77,7 @@ men hvorfor det er bygget slik:
|
||||||
|
|
||||||
- **Alt er noder og edges.** Ingen separate tabeller. Visninger
|
- **Alt er noder og edges.** Ingen separate tabeller. Visninger
|
||||||
er spørringer mot grafen.
|
er spørringer mot grafen.
|
||||||
- **Unix-filosofi.** Portvokteren orkestrerer, CLI-verktøy gjør
|
- **Unix-filosofi.** Vaktmesteren orkestrerer, CLI-verktøy gjør
|
||||||
jobben. Én ting, gjort godt. Delt verktøykasse.
|
jobben. Én ting, gjort godt. Delt verktøykasse.
|
||||||
- **Selvdokumenterende system.** Systemet dokumenterer seg selv
|
- **Selvdokumenterende system.** Systemet dokumenterer seg selv
|
||||||
som noder i seg selv. Docs er ikke filer — de er graf-data.
|
som noder i seg selv. Docs er ikke filer — de er graf-data.
|
||||||
|
|
@ -87,7 +87,7 @@ men hvorfor det er bygget slik:
|
||||||
by design, ikke konfigurasjon.
|
by design, ikke konfigurasjon.
|
||||||
- **Noder er sentrum.** Brukere, team, innhold — alt er noder.
|
- **Noder er sentrum.** Brukere, team, innhold — alt er noder.
|
||||||
Tilgang via materialisert tilgangsmatrise fra edges.
|
Tilgang via materialisert tilgangsmatrise fra edges.
|
||||||
- **Portvokteren er tynn.** Auth, HTTP-ruting, STDB-synk.
|
- **Vaktmesteren er tynn.** Auth, HTTP-ruting, STDB-synk.
|
||||||
All logikk i CLI-verktøy og synops-common.
|
All logikk i CLI-verktøy og synops-common.
|
||||||
- **Generisk dispatch.** `synops-{job_type} --payload-json`.
|
- **Generisk dispatch.** `synops-{job_type} --payload-json`.
|
||||||
Nytt verktøy = binary i PATH. Ingen rekompilering.
|
Nytt verktøy = binary i PATH. Ingen rekompilering.
|
||||||
|
|
@ -108,7 +108,7 @@ Nummerert sekvens fra ren server til kjørende system:
|
||||||
4. Start Docker-tjenester (PG, Authentik, LiteLLM, Whisper, LiveKit)
|
4. Start Docker-tjenester (PG, Authentik, LiteLLM, Whisper, LiveKit)
|
||||||
5. Kjør PG-migrasjoner (skjema + seed)
|
5. Kjør PG-migrasjoner (skjema + seed)
|
||||||
6. Konfigurer Authentik (OIDC-provider, redirect URIs)
|
6. Konfigurer Authentik (OIDC-provider, redirect URIs)
|
||||||
7. Bygg og deploy portvokteren (cargo build, systemd)
|
7. Bygg og deploy vaktmesteren (cargo build, systemd)
|
||||||
8. Bygg og deploy SvelteKit (npm build, systemd)
|
8. Bygg og deploy SvelteKit (npm build, systemd)
|
||||||
9. Bygg CLI-verktøy (cargo build per tool)
|
9. Bygg CLI-verktøy (cargo build per tool)
|
||||||
10. Konfigurer Caddy (Caddyfile, reload)
|
10. Konfigurer Caddy (Caddyfile, reload)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
```
|
```
|
||||||
Lag 1: LLM-leverandør (Claude API, OpenAI, etc.) → utenfor vår kontroll
|
Lag 1: LLM-leverandør (Claude API, OpenAI, etc.) → utenfor vår kontroll
|
||||||
Lag 2: LiteLLM (AI Gateway) → lokal Docker
|
Lag 2: LiteLLM (AI Gateway) → lokal Docker
|
||||||
Lag 3: Portvokteren → lokal native (systemd)
|
Lag 3: Vaktmesteren → lokal native (systemd)
|
||||||
Lag 4: CLI-verktøy (synops-*) → per-kall, isolert
|
Lag 4: CLI-verktøy (synops-*) → per-kall, isolert
|
||||||
Lag 5: PostgreSQL → lokal Docker, SPOF
|
Lag 5: PostgreSQL → lokal Docker, SPOF
|
||||||
```
|
```
|
||||||
|
|
@ -14,11 +14,11 @@ Lag 5: PostgreSQL → lokal Docker, SPOF
|
||||||
|
|
||||||
### Bot-nedetid
|
### Bot-nedetid
|
||||||
|
|
||||||
Portvokteren overvåker `synops-respond` sin exit-kode. Ved feil:
|
Vaktmesteren overvåker `synops-respond` sin exit-kode. Ved feil:
|
||||||
|
|
||||||
```
|
```
|
||||||
@bot (ingen respons på 30 sek)
|
@bot (ingen respons på 30 sek)
|
||||||
→ Portvokteren sender automatisk i chatten:
|
→ Vaktmesteren sender automatisk i chatten:
|
||||||
"⚠ Boten er midlertidig utilgjengelig.
|
"⚠ Boten er midlertidig utilgjengelig.
|
||||||
Meldingen din er lagret og blir besvart
|
Meldingen din er lagret og blir besvart
|
||||||
når tjenesten er tilbake."
|
når tjenesten er tilbake."
|
||||||
|
|
@ -31,12 +31,12 @@ kan den prosessere ubesvarte meldinger.
|
||||||
|
|
||||||
### Healthcheck
|
### Healthcheck
|
||||||
|
|
||||||
Portvokteren eksponerer `/health` som sjekker:
|
Vaktmesteren eksponerer `/health` som sjekker:
|
||||||
- PG-tilkobling
|
- PG-tilkobling
|
||||||
- LiteLLM-tilgjengelighet
|
- LiteLLM-tilgjengelighet
|
||||||
- Disk-status
|
- Disk-status
|
||||||
|
|
||||||
Systemd restarter portvokteren ved gjentatte feil.
|
Systemd restarter vaktmesteren ved gjentatte feil.
|
||||||
|
|
||||||
## LLM fallback-kjede
|
## LLM fallback-kjede
|
||||||
|
|
||||||
|
|
@ -53,18 +53,18 @@ synops-respond → LiteLLM
|
||||||
|
|
||||||
Brukeren merker kanskje kvalitetsforskjell, men tjenesten er
|
Brukeren merker kanskje kvalitetsforskjell, men tjenesten er
|
||||||
oppe. Fallback-kjeden konfigureres i LiteLLM — ingen endring
|
oppe. Fallback-kjeden konfigureres i LiteLLM — ingen endring
|
||||||
i portvokteren eller synops-respond.
|
i vaktmesteren eller synops-respond.
|
||||||
|
|
||||||
## Ekstern API-bot og CLI-verktøy
|
## Ekstern API-bot og CLI-verktøy
|
||||||
|
|
||||||
En LLM via API har ikke shell-tilgang. Den trenger det heller
|
En LLM via API har ikke shell-tilgang. Den trenger det heller
|
||||||
ikke — portvokteren er mellomleddet.
|
ikke — vaktmesteren er mellomleddet.
|
||||||
|
|
||||||
### Function calling / tool use
|
### Function calling / tool use
|
||||||
|
|
||||||
```
|
```
|
||||||
Bruker: "@bot sjekk om RSS-feeden oppdaterte seg"
|
Bruker: "@bot sjekk om RSS-feeden oppdaterte seg"
|
||||||
→ portvokteren → synops-respond → LLM API
|
→ vaktmesteren → synops-respond → LLM API
|
||||||
|
|
||||||
LLM svarer med structured output:
|
LLM svarer med structured output:
|
||||||
{
|
{
|
||||||
|
|
@ -75,21 +75,21 @@ LLM svarer med structured output:
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
Portvokteren:
|
Vaktmesteren:
|
||||||
1. Poster chat-svaret i samtalen
|
1. Poster chat-svaret i samtalen
|
||||||
2. Spawner: synops-rss --payload-json '{"collection_id":"abc123"}'
|
2. Spawner: synops-rss --payload-json '{"collection_id":"abc123"}'
|
||||||
3. Poster resultatet som oppfølgingsmelding
|
3. Poster resultatet som oppfølgingsmelding
|
||||||
```
|
```
|
||||||
|
|
||||||
LLM-en beskriver *hva* som skal gjøres. Portvokteren *gjør*
|
LLM-en beskriver *hva* som skal gjøres. Vaktmesteren *gjør*
|
||||||
det. Navnekonvensjonen (`synops-{tool}`) betyr at portvokteren
|
det. Navnekonvensjonen (`synops-{tool}`) betyr at vaktmesteren
|
||||||
kan dispatche uten hardkodet mapping — samme generiske dispatch
|
kan dispatche uten hardkodet mapping — samme generiske dispatch
|
||||||
som jobbkøen (se `docs/retninger/unix_filosofi.md`).
|
som jobbkøen (se `docs/retninger/unix_filosofi.md`).
|
||||||
|
|
||||||
### Tilgangskontroll for actions
|
### Tilgangskontroll for actions
|
||||||
|
|
||||||
Ikke alle brukere skal kunne trigge alle verktøy via `@bot`.
|
Ikke alle brukere skal kunne trigge alle verktøy via `@bot`.
|
||||||
Portvokteren sjekker:
|
Vaktmesteren sjekker:
|
||||||
|
|
||||||
1. Brukerens rolle i konteksten (owner/admin/member/reader)
|
1. Brukerens rolle i konteksten (owner/admin/member/reader)
|
||||||
2. Verktøyets tilgangsnivå (fra `cli_tool`-nodens metadata)
|
2. Verktøyets tilgangsnivå (fra `cli_tool`-nodens metadata)
|
||||||
|
|
@ -104,9 +104,9 @@ En `reader` kan spørre `@bot` om informasjon, men ikke trigge
|
||||||
|-----------|-----------|----------|------------------|
|
|-----------|-----------|----------|------------------|
|
||||||
| Claude API nede | LiteLLM timeout | Neste modell i kjeden | Svarer, kanskje litt dårligere |
|
| Claude API nede | LiteLLM timeout | Neste modell i kjeden | Svarer, kanskje litt dårligere |
|
||||||
| Alle LLM-er nede | synops-respond exit != 0 | Statisk "utilgjengelig" + work_item | Vet at meldingen er mottatt |
|
| Alle LLM-er nede | synops-respond exit != 0 | Statisk "utilgjengelig" + work_item | Vet at meldingen er mottatt |
|
||||||
| Portvokteren nede | Systemd healthcheck → restart | CLI fungerer for Claude Code | Web-brukere venter, terminal funker |
|
| Vaktmesteren nede | Systemd healthcheck → restart | CLI fungerer for Claude Code | Web-brukere venter, terminal funker |
|
||||||
| PG nede | Connection refused | Alt stopper | Eneste reelle SPOF |
|
| PG nede | Connection refused | Alt stopper | Eneste reelle SPOF |
|
||||||
| WebSocket nede | Portvokteren restarter | Frontend rekobler automatisk | Sanntid midlertidig borte, data trygt |
|
| WebSocket nede | Vaktmesteren restarter | Frontend rekobler automatisk | Sanntid midlertidig borte, data trygt |
|
||||||
|
|
||||||
## PG som eneste SPOF
|
## PG som eneste SPOF
|
||||||
|
|
||||||
|
|
@ -123,7 +123,7 @@ Mitigering:
|
||||||
## Onboarding som statisk dispatch
|
## Onboarding som statisk dispatch
|
||||||
|
|
||||||
Første `@bot` i en ny brukers velkomst-chat trenger ikke
|
Første `@bot` i en ny brukers velkomst-chat trenger ikke
|
||||||
LLM-roundtrip. Portvokteren gjenkjenner mønsteret og serverer
|
LLM-roundtrip. Vaktmesteren gjenkjenner mønsteret og serverer
|
||||||
onboarding-noden direkte:
|
onboarding-noden direkte:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
|
@ -141,6 +141,6 @@ Etter første melding fungerer chatten normalt med LLM.
|
||||||
## Bygger på
|
## Bygger på
|
||||||
- `docs/infra/ai_gateway.md` — LiteLLM fallback-kjeder
|
- `docs/infra/ai_gateway.md` — LiteLLM fallback-kjeder
|
||||||
- `docs/retninger/unix_filosofi.md` — generisk dispatch
|
- `docs/retninger/unix_filosofi.md` — generisk dispatch
|
||||||
- `docs/retninger/maskinrommet.md` — portvokter-rollen
|
- `docs/retninger/maskinrommet.md` — vaktmester-rollen
|
||||||
- `docs/concepts/arbeidstavlen.md` — @bot-konvensjonen
|
- `docs/concepts/arbeidstavlen.md` — @bot-konvensjonen
|
||||||
- `docs/concepts/selvdokumenterende_system.md` — onboarding-node
|
- `docs/concepts/selvdokumenterende_system.md` — onboarding-node
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
**Status: Besluttet. Revidert mars 2026 — SpacetimeDB fjernet.**
|
**Status: Besluttet. Revidert mars 2026 — SpacetimeDB fjernet.**
|
||||||
|
|
||||||
> PostgreSQL er eneste datakilde. Sanntid via PG `LISTEN/NOTIFY`
|
> PostgreSQL er eneste datakilde. Sanntid via PG `LISTEN/NOTIFY`
|
||||||
> og WebSocket i portvokteren. CAS lagrer binærdata.
|
> og WebSocket i vaktmesteren. CAS lagrer binærdata.
|
||||||
> Apache AGE legges til ved behov for Cypher-traverseringer.
|
> Apache AGE legges til ved behov for Cypher-traverseringer.
|
||||||
|
|
||||||
## Lagmodell
|
## Lagmodell
|
||||||
|
|
@ -12,29 +12,29 @@
|
||||||
GUI (SvelteKit)
|
GUI (SvelteKit)
|
||||||
│ skriv │ les (sanntid, WebSocket)
|
│ skriv │ les (sanntid, WebSocket)
|
||||||
▼ ▼
|
▼ ▼
|
||||||
Portvokteren (Rust) Portvokteren ──WebSocket──→ GUI
|
Vaktmesteren (Rust) Vaktmesteren ──WebSocket──→ GUI
|
||||||
│ validering ▲
|
│ validering ▲
|
||||||
└──→ PostgreSQL ──NOTIFY──→──┘
|
└──→ PostgreSQL ──NOTIFY──→──┘
|
||||||
```
|
```
|
||||||
|
|
||||||
### Skrivestien
|
### Skrivestien
|
||||||
GUI → portvokteren → validering → PG. Frontend oppdateres via
|
GUI → vaktmesteren → validering → PG. Frontend oppdateres via
|
||||||
WebSocket-push utløst av PG NOTIFY.
|
WebSocket-push utløst av PG NOTIFY.
|
||||||
|
|
||||||
### Lesestien (sanntid)
|
### Lesestien (sanntid)
|
||||||
PG → portvokteren → WebSocket → GUI.
|
PG → vaktmesteren → WebSocket → GUI.
|
||||||
Portvokteren holder en in-memory cache av aktive subscriptions
|
Vaktmesteren holder en in-memory cache av aktive subscriptions
|
||||||
og pusher relevante endringer til tilkoblede klienter.
|
og pusher relevante endringer til tilkoblede klienter.
|
||||||
|
|
||||||
### Lesestien (tunge spørringer)
|
### Lesestien (tunge spørringer)
|
||||||
GUI → portvokteren → PG.
|
GUI → vaktmesteren → PG.
|
||||||
Fulltekstsøk, pgvector, statistikk, AGE-traverseringer.
|
Fulltekstsøk, pgvector, statistikk, AGE-traverseringer.
|
||||||
|
|
||||||
## PostgreSQL — eneste datakilde
|
## PostgreSQL — eneste datakilde
|
||||||
|
|
||||||
Én sannhetskilde. Ingen synk, ingen konsistensproblemer:
|
Én sannhetskilde. Ingen synk, ingen konsistensproblemer:
|
||||||
|
|
||||||
- **Sanntid:** `LISTEN/NOTIFY` → portvokteren → WebSocket
|
- **Sanntid:** `LISTEN/NOTIFY` → vaktmesteren → WebSocket
|
||||||
- **Fulltekstsøk:** `tsvector` på `nodes.content` og `nodes.title`
|
- **Fulltekstsøk:** `tsvector` på `nodes.content` og `nodes.title`
|
||||||
- **Semantisk søk:** pgvector for embedding-basert likhet
|
- **Semantisk søk:** pgvector for embedding-basert likhet
|
||||||
- **Graftraversering:** rekursive CTEs, Apache AGE ved behov
|
- **Graftraversering:** rekursive CTEs, Apache AGE ved behov
|
||||||
|
|
@ -63,11 +63,11 @@ Se [maskinrommet](maskinrommet.md).
|
||||||
|
|
||||||
## Sanntid via PG LISTEN/NOTIFY
|
## Sanntid via PG LISTEN/NOTIFY
|
||||||
|
|
||||||
PG har innebygd pub/sub. Portvokteren lytter og videresender:
|
PG har innebygd pub/sub. Vaktmesteren lytter og videresender:
|
||||||
|
|
||||||
```
|
```
|
||||||
PG: NOTIFY node_changed, '{"id":"abc","kind":"content"}'
|
PG: NOTIFY node_changed, '{"id":"abc","kind":"content"}'
|
||||||
→ Portvokteren mottar
|
→ Vaktmesteren mottar
|
||||||
→ Sjekker tilgangsmatrise: hvem skal se denne endringen?
|
→ Sjekker tilgangsmatrise: hvem skal se denne endringen?
|
||||||
→ Pusher til relevante WebSocket-tilkoblinger
|
→ Pusher til relevante WebSocket-tilkoblinger
|
||||||
→ Frontend oppdaterer reaktivt
|
→ Frontend oppdaterer reaktivt
|
||||||
|
|
@ -97,9 +97,9 @@ CREATE TRIGGER nodes_notify
|
||||||
|
|
||||||
Tilsvarende for edges.
|
Tilsvarende for edges.
|
||||||
|
|
||||||
### WebSocket i portvokteren
|
### WebSocket i vaktmesteren
|
||||||
|
|
||||||
Portvokteren holder:
|
Vaktmesteren holder:
|
||||||
- Map av tilkoblede klienter → brukerens node_id
|
- Map av tilkoblede klienter → brukerens node_id
|
||||||
- Map av node_id → synlige noder (fra node_access)
|
- Map av node_id → synlige noder (fra node_access)
|
||||||
- Ved NOTIFY: filtrer på tilgang, push til relevante klienter
|
- Ved NOTIFY: filtrer på tilgang, push til relevante klienter
|
||||||
|
|
@ -130,6 +130,6 @@ lærdommer: `docs/erfaringer/spacetimedb_integrasjon.md`.
|
||||||
beregnet fra edge-grafen, brukes for WebSocket-filtrering
|
beregnet fra edge-grafen, brukes for WebSocket-filtrering
|
||||||
- [Universell input og mottak](universell_input.md) — noder og edges
|
- [Universell input og mottak](universell_input.md) — noder og edges
|
||||||
er datamodellen for alle tre primitiver
|
er datamodellen for alle tre primitiver
|
||||||
- [Maskinrommet / Portvokteren](maskinrommet.md) — CAS-pruning,
|
- [Maskinrommet / Vaktmesteren](maskinrommet.md) — CAS-pruning,
|
||||||
edge-drevet ressursorkestrering, validering før skriving,
|
edge-drevet ressursorkestrering, validering før skriving,
|
||||||
WebSocket-endepunkt for sanntid
|
WebSocket-endepunkt for sanntid
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ samme maskin.
|
||||||
|
|
||||||
Compute-separasjon er en konfigurasjon, ikke en arkitekturendring.
|
Compute-separasjon er en konfigurasjon, ikke en arkitekturendring.
|
||||||
|
|
||||||
## Evolusjon: Maskinrommet → Portvokteren
|
## Evolusjon: Maskinrommet → Vaktmesteren
|
||||||
|
|
||||||
Maskinrommet ble bygget som en monolitt — auth, validering,
|
Maskinrommet ble bygget som en monolitt — auth, validering,
|
||||||
prosessering, jobbkø i én binær. Med unix-filosofi-
|
prosessering, jobbkø i én binær. Med unix-filosofi-
|
||||||
|
|
@ -193,20 +193,20 @@ prosessering til CLI-verktøy. Det som blir igjen er:
|
||||||
3. **Sanntid** — PG LISTEN/NOTIFY → WebSocket til frontend
|
3. **Sanntid** — PG LISTEN/NOTIFY → WebSocket til frontend
|
||||||
4. **Jobbkø-dispatch** — poll PG, spawn CLI-verktøy
|
4. **Jobbkø-dispatch** — poll PG, spawn CLI-verktøy
|
||||||
|
|
||||||
Dette er en **portvokter**, ikke et maskinrom. Når uttynningen er
|
Dette er en **vaktmester**, ikke et maskinrom. Når uttynningen er
|
||||||
ferdig, renames `maskinrommet/` til `portvokteren/` og systemd-
|
ferdig, renames `maskinrommet/` til `vaktmesteren/` og systemd-
|
||||||
tjenesten oppdateres. Navnet skal reflektere rollen: vokter porten,
|
tjenesten oppdateres. Navnet skal reflektere rollen: vokter porten,
|
||||||
gjør ikke jobben.
|
gjør ikke jobben.
|
||||||
|
|
||||||
**Hva dette gir:**
|
**Hva dette gir:**
|
||||||
- Portvokteren dør → frontend stopper, men CLI-verktøy fungerer.
|
- Vaktmesteren dør → frontend stopper, men CLI-verktøy fungerer.
|
||||||
Claude jobber videre, scripts kjører, terminalen funker.
|
Claude jobber videre, scripts kjører, terminalen funker.
|
||||||
- Et CLI-verktøy dør → bare den funksjonen stopper. Alt annet
|
- Et CLI-verktøy dør → bare den funksjonen stopper. Alt annet
|
||||||
er upåvirket.
|
er upåvirket.
|
||||||
- Portvokteren blir så enkel at den nesten aldri feiler.
|
- Vaktmesteren blir så enkel at den nesten aldri feiler.
|
||||||
|
|
||||||
**Edge-validering og tilgangskontroll** flyttes til `synops-common`
|
**Edge-validering og tilgangskontroll** flyttes til `synops-common`
|
||||||
(delt lib) — brukes av både portvokteren og CLI-verktøy.
|
(delt lib) — brukes av både vaktmesteren og CLI-verktøy.
|
||||||
|
|
||||||
## Forhold til andre retninger
|
## Forhold til andre retninger
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ synops-transcribe --cas-hash abc123 --model medium
|
||||||
- **Navnekonvensjon:** `synops-<verb>` (f.eks. `synops-transcribe`)
|
- **Navnekonvensjon:** `synops-<verb>` (f.eks. `synops-transcribe`)
|
||||||
- **Input:** args + stdin + env-variabler (DATABASE_URL, CAS_ROOT)
|
- **Input:** args + stdin + env-variabler (DATABASE_URL, CAS_ROOT)
|
||||||
- **Payload-modus:** `--payload-json <json>` for jobbkø-dispatch
|
- **Payload-modus:** `--payload-json <json>` for jobbkø-dispatch
|
||||||
(verktøyet parser selv, portvokteren trenger ikke kjenne argumentene)
|
(verktøyet parser selv, vaktmesteren trenger ikke kjenne argumentene)
|
||||||
- **Output:** stdout (strukturert — JSON eller markdown)
|
- **Output:** stdout (strukturert — JSON eller markdown)
|
||||||
- **Feilhåndtering:** stderr for feilmeldinger, exit-kode != 0 ved feil
|
- **Feilhåndtering:** stderr for feilmeldinger, exit-kode != 0 ved feil
|
||||||
- **Ingen tilstandsendring uten flagg:** lesing er default, skriving krever
|
- **Ingen tilstandsendring uten flagg:** lesing er default, skriving krever
|
||||||
|
|
@ -78,7 +78,7 @@ synops-transcribe --cas-hash abc123 --model medium
|
||||||
|
|
||||||
## Generisk dispatch
|
## Generisk dispatch
|
||||||
|
|
||||||
Portvokteren trenger null konfigurasjon per verktøy. Bare en
|
Vaktmesteren trenger null konfigurasjon per verktøy. Bare en
|
||||||
navnekonvensjon:
|
navnekonvensjon:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
|
@ -89,10 +89,10 @@ cmd.arg("--payload-json").arg(&job.payload_json);
|
||||||
|
|
||||||
`job_type: "transcribe"` → `synops-transcribe --payload-json '{...}'`.
|
`job_type: "transcribe"` → `synops-transcribe --payload-json '{...}'`.
|
||||||
Verktøyet parser payload selv. Nytt verktøy = legg binary i PATH,
|
Verktøyet parser payload selv. Nytt verktøy = legg binary i PATH,
|
||||||
bruk riktig `job_type` i køen. Ingen rekompilering av portvokteren.
|
bruk riktig `job_type` i køen. Ingen rekompilering av vaktmesteren.
|
||||||
|
|
||||||
`cli_tool`-noder i PG bærer metadata (timeout, cpu_weight,
|
`cli_tool`-noder i PG bærer metadata (timeout, cpu_weight,
|
||||||
dokumentasjon) — men ikke dispatch-logikk. Portvokteren leser
|
dokumentasjon) — men ikke dispatch-logikk. Vaktmesteren leser
|
||||||
timeout og cpu_weight fra noden, men selve invokasjon er
|
timeout og cpu_weight fra noden, men selve invokasjon er
|
||||||
konvensjonsbasert.
|
konvensjonsbasert.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue