Rydd sidelinja-referanser: generiske AI-nivåer + synops.no-domener

AI-aliaser: sidelinja/rutine → synops/low, sidelinja/resonering →
synops/high. Fire nivåer i LiteLLM: low/medium/high/extreme.
Oppdatert i: LiteLLM config, PG ai_job_routing, all Rust-kode
(maskinrommet + 5 CLI-verktøy).

Domener: sidelinja.org → synops.no i fallback-URLer, health-sjekker,
LiveKit WSS, bandwidth-logger, docs/erfaringer, docs/setup,
reference/server-state, .env.example.

Docker container-navn (sidelinja-*) beholdes — styrt av
COMPOSE_PROJECT_NAME i /srv/synops/.env, endres separat ved behov.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
vegard 2026-03-19 17:22:22 +00:00
parent 09d0477680
commit 69997c6e87
22 changed files with 11401 additions and 67 deletions

View file

@ -14,7 +14,7 @@ XAI_API_KEY=
LITELLM_MASTER_KEY=sk-sidelinja-dev-1234
# === Authentik OIDC ===
AUTHENTIK_ISSUER=https://auth.sidelinja.org/application/o/sidelinja/
AUTHENTIK_ISSUER=https://auth.synops.no/application/o/sidelinja/
AUTHENTIK_CLIENT_ID=
AUTHENTIK_CLIENT_SECRET=

View file

@ -40,7 +40,7 @@ callbacks: {
## 3. Redirect-URI i Authentik
`@auth/sveltekit` bruker callback-URL `https://<domain>/auth/callback/<provider-id>`. For oss: `https://sidelinja.org/auth/callback/authentik`.
`@auth/sveltekit` bruker callback-URL `https://<domain>/auth/callback/<provider-id>`. For oss: `https://ws.synops.no/auth/callback/authentik`.
Denne MÅ være registrert som redirect-URI i Authentik sin OAuth2-provider. Verifiser via:

View file

@ -2,24 +2,24 @@
## Oversikt
Authentik kjører på `auth.sidelinja.org` og fungerer som SSO for alle
Authentik kjører på `auth.synops.no` og fungerer som SSO for alle
Synops-tjenester. To OIDC-providere er konfigurert:
| Provider | Application | Slug | Bruk |
|---|---|---|---|
| `forgejo` | forgejo | `forgejo` | Git-hosting (git.sidelinja.org) |
| `forgejo` | forgejo | `forgejo` | Git-hosting (git.synops.no) |
| `sidelinja-web` | Sidelinja | `sidelinja` | Hovedapplikasjon (sidelinja.org) |
## Sidelinja OIDC-provider
### Endepunkter
- **Issuer:** `https://auth.sidelinja.org/application/o/sidelinja/`
- **Discovery:** `https://auth.sidelinja.org/application/o/sidelinja/.well-known/openid-configuration`
- **Authorization:** `https://auth.sidelinja.org/application/o/authorize/`
- **Token:** `https://auth.sidelinja.org/application/o/token/`
- **Userinfo:** `https://auth.sidelinja.org/application/o/userinfo/`
- **JWKS:** `https://auth.sidelinja.org/application/o/sidelinja/jwks/`
- **Issuer:** `https://auth.synops.no/application/o/sidelinja/`
- **Discovery:** `https://auth.synops.no/application/o/sidelinja/.well-known/openid-configuration`
- **Authorization:** `https://auth.synops.no/application/o/authorize/`
- **Token:** `https://auth.synops.no/application/o/token/`
- **Userinfo:** `https://auth.synops.no/application/o/userinfo/`
- **JWKS:** `https://auth.synops.no/application/o/sidelinja/jwks/`
### Konfigurasjon
@ -34,7 +34,7 @@ Synops-tjenester. To OIDC-providere er konfigurert:
| Modus | URL | Formål |
|---|---|---|
| strict | `https://sidelinja.org/auth/callback/authentik` | Produksjon |
| strict | `https://ws.synops.no/auth/callback/authentik` | Produksjon |
| regex | `http://localhost:\d+/auth/callback/authentik` | Lokal utvikling |
### Scopes
@ -44,7 +44,7 @@ Provideren tilbyr: `openid`, `email`, `profile`, `offline_access`.
### Miljøvariabler (.env på server)
```
AUTHENTIK_ISSUER=https://auth.sidelinja.org/application/o/sidelinja/
AUTHENTIK_ISSUER=https://auth.synops.no/application/o/sidelinja/
AUTHENTIK_CLIENT_ID=<fra Authentik>
AUTHENTIK_CLIENT_SECRET=<fra Authentik>
```
@ -56,7 +56,7 @@ for JWT-validering.
Maskinrommet (Rust/axum) validerer access tokens utstedt av denne provideren:
1. Hent JWKS fra `https://auth.sidelinja.org/application/o/sidelinja/jwks/`
1. Hent JWKS fra `https://auth.synops.no/application/o/sidelinja/jwks/`
2. Valider signatur (RS256), issuer, og utløpstid
3. Slå opp `sub`-claim i `auth_identities`-tabellen → `node_id`
@ -87,14 +87,14 @@ Bruk tokenet med: `Authorization: Bearer <token>`
```bash
# OIDC discovery
curl -s https://auth.sidelinja.org/application/o/sidelinja/.well-known/openid-configuration | jq .issuer
curl -s https://auth.synops.no/application/o/sidelinja/.well-known/openid-configuration | jq .issuer
# JWKS (for JWT-validering)
curl -s https://auth.sidelinja.org/application/o/sidelinja/jwks/ | jq '.keys | length'
curl -s https://auth.synops.no/application/o/sidelinja/jwks/ | jq '.keys | length'
# List providere via API
curl -s -H "Authorization: Bearer <token>" \
https://auth.sidelinja.org/api/v3/providers/oauth2/ | jq '.results[].name'
https://auth.synops.no/api/v3/providers/oauth2/ | jq '.results[].name'
```
## Legge til ny redirect URI
@ -104,14 +104,14 @@ Hvis en ny tjeneste trenger OIDC (f.eks. maskinrommet med egen callback):
```bash
# Hent provider pk
curl -s -H "Authorization: Bearer <token>" \
https://auth.sidelinja.org/api/v3/providers/oauth2/?name=sidelinja-web | jq '.results[0].pk'
https://auth.synops.no/api/v3/providers/oauth2/?name=sidelinja-web | jq '.results[0].pk'
# Oppdater redirect_uris (PATCH)
curl -s -X PATCH -H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
https://auth.sidelinja.org/api/v3/providers/oauth2/<pk>/ \
https://auth.synops.no/api/v3/providers/oauth2/<pk>/ \
-d '{"redirect_uris": [
{"matching_mode": "strict", "url": "https://sidelinja.org/auth/callback/authentik"},
{"matching_mode": "strict", "url": "https://ws.synops.no/auth/callback/authentik"},
{"matching_mode": "regex", "url": "http://localhost:\\d+/auth/callback/authentik"},
{"matching_mode": "strict", "url": "https://ny-tjeneste.sidelinja.org/callback"}
]}'

View file

@ -0,0 +1,76 @@
# Header-unifikasjon, tema og panel-forbedringer
Diskusjonsnotat fra 2025-03-19. Grunnlag for neste implementeringsplan.
## Problemstilling
Headeren er inkonsistent mellom "Min arbeidsflate" (`+page.svelte`) og
samlinger (`/collection/[id]` med `ContextHeader.svelte`). Bruker mister
kontekst og verktøy ved kontekstbytte. Innstillinger finnes bare på
personlig flate. Fargevelgeren er for begrenset.
## Beslutninger
### 1. Én header-komponent overalt
ContextHeader brukes på alle sider — personlig flate og samlinger.
Inneholder alltid:
- **Kontekst-velger** (venstre): dropdown med arbeidsflater, rename,
ny, slett. Alltid tilgjengelig uansett hvilken flate du er på.
- **Verktøymeny** (midten-høyre): legge til paneler.
- **Tilkoblingsstatus** (før innstillinger, konsekvent plassert)
- **Innstillinger** (lengst til høyre): tema for *denne* flaten, logg ut.
### 2. Tema per arbeidsflate med arv
Tre lag (som layout):
1. **Flate-spesifikt** — lagret i samlingens/workspace-nodens metadata.preferences.theme
2. **Personlig default** — fra "Min arbeidsflate" sin tema
3. **Plattform-default** — nøytral mørk (#0a0a0b / #1c1c20 / #6366f1)
Arving: ny flate arver fra personlig. Endring lagres på flaten.
### 3. Fargevelger
Ikke tre hue-slidere med bare gråtoner. I stedet:
- HSL-basert: hue-stripe + saturation/lightness
- Eller: forhåndsdefinerte paletter + egendefinert modus
- Full fargepalett tilgjengelig, ikke begrenset til nøytrale toner
### 4. Traits vs verktøymeny
Verktøymenyen viser paneler som kan legges til:
- Aktiverte traits vises som standard (med ikon)
- Andre traits vises som "legg til" (grå, med forklaring)
- "Administrer traits" er en admin-handling (f.eks. ⚙️ nederst i menyen)
Brukeren trenger ikke forstå trait-konseptet — de ser verktøy.
### 5. Slett arbeidsflate
Bekreftelsesdialog som teller innhold:
- "Denne arbeidsflaten inneholder X noder."
- Innhold forblir tilgjengelig i andre kontekster (edges).
- Sletting fjerner samlingsnoden og tilhørende edges.
### 6. Panel-resize (BlockShell)
Paneler (BlockShell-bokser) bør ha synlige resize-handles på alle kanter,
ikke bare hjørner. Fritt resize i begge retninger. Sjekk nåværende
implementasjon — kanskje bare UI-forbedring, kanskje logikk-endring.
### 7. Tilkoblingsstatus
Flyttes til konsekvent posisjon: like før innstillinger-ikonet
(nest sist til høyre), eller helt til venstre i header-right.
Viktigst: alltid på samme sted.
## Filer som berøres
- `frontend/src/lib/components/ContextHeader.svelte` — hovedkomponent, utvides
- `frontend/src/routes/+page.svelte` — erstatt inline header med ContextHeader
- `frontend/src/routes/collection/[id]/+page.svelte` — allerede bruker ContextHeader
- `frontend/src/lib/components/blockshell/BlockShell.svelte` — resize-handles
- `frontend/src/app.css` — CSS custom properties for tema
- `frontend/src/lib/workspace/types.ts` — evt. tema-typer

View file

@ -41,7 +41,7 @@ source ~/.cargo/env
```bash
cd ~
git clone ssh://git@git.sidelinja.org:222/vegard/synops.git
git clone ssh://git@git.synops.no:222/vegard/synops.git
cd synops
```

View file

@ -103,7 +103,7 @@ cat > /srv/synops/.env << 'EOF'
# === Domener ===
DOMAIN_SIDELINJA=sidelinja.org
DOMAIN_VEGARD=vegard.info
DOMAIN_AUTH=auth.sidelinja.org
DOMAIN_AUTH=auth.synops.no
COMPOSE_PROJECT_NAME=sidelinja
# === PostgreSQL ===
@ -130,7 +130,7 @@ LIVEKIT_API_SECRET=<generer med: openssl rand -hex 32>
OPENROUTER_API_KEY=<fra openrouter.ai>
# === Maskinrommet ===
AUTHENTIK_ISSUER=https://auth.sidelinja.org/application/o/sidelinja/
AUTHENTIK_ISSUER=https://auth.synops.no/application/o/sidelinja/
AUTHENTIK_CLIENT_ID=<fra Authentik OIDC-provider>
AUTHENTIK_CLIENT_SECRET=<fra Authentik OIDC-provider>
@ -153,7 +153,7 @@ Tjenestene startes i rekkefølge fordi noen avhenger av andre. Alle defineres i
1. **Docker-nettverk:** Opprett internt nettverk `sidelinja-net`
2. **PostgreSQL:** Start, opprett databaser for Authentik og Forgejo, verifiser (`pg_isready`)
3. **Caddy:** Start med Caddyfile for alle domener, verifiser at HTTPS fungerer
4. **Authentik:** Start, gjennomfør initial setup via `https://auth.sidelinja.org`
4. **Authentik:** Start, gjennomfør initial setup via `https://auth.synops.no`
5. **Forgejo:** Start med Authentik som OAuth2-provider, opprett organisasjon og repo
### Lag B: Sanntid (krever nettverk)
@ -185,8 +185,8 @@ networks:
services:
caddy: # Eneste tjeneste med eksponerte porter (80, 443)
postgres: # data:/srv/synops/data/postgres
authentik: # SSO for alle domener, på auth.sidelinja.org
forgejo: # data:/srv/synops/data/forgejo, på git.sidelinja.org
authentik: # SSO for alle domener, på auth.synops.no
forgejo: # data:/srv/synops/data/forgejo, på git.synops.no
maskinrommet: # Rust/axum API, intern port 3100, proxyet via Caddy
livekit: # Intern port, proxyet via Caddy
sveltekit: # Intern port, proxyet via Caddy
@ -198,7 +198,7 @@ services:
```caddyfile
# === SSO ===
auth.sidelinja.org {
auth.synops.no {
reverse_proxy authentik-server:9000
}
@ -225,7 +225,7 @@ api.sidelinja.org {
}
# === Forgejo (Git) ===
git.sidelinja.org {
git.synops.no {
reverse_proxy forgejo:3000
}
@ -264,7 +264,7 @@ CREATE DATABASE forgejo OWNER forgejo;
## 9. Authentik: Initial konfigurasjon
Etter oppstart, gå til `https://auth.sidelinja.org/if/flow/initial-setup/`:
Etter oppstart, gå til `https://auth.synops.no/if/flow/initial-setup/`:
1. Opprett admin-konto
2. Opprett OAuth2/OpenID Connect-provider for Forgejo
3. Opprett OAuth2/OpenID Connect-provider for SvelteKit (senere)
@ -275,7 +275,7 @@ Etter oppstart, gå til `https://auth.sidelinja.org/if/flow/initial-setup/`:
Forgejo konfigureres med Authentik som OAuth2-kilde:
- Authentication Source: OAuth2
- Provider: OpenID Connect
- Discovery URL: `https://auth.sidelinja.org/application/o/<slug>/.well-known/openid-configuration`
- Discovery URL: `https://auth.synops.no/application/o/<slug>/.well-known/openid-configuration`
- Etter oppsett: opprett organisasjon `sidelinja`, opprett repo `sidelinja`
## 11. Backup-strategi
@ -519,8 +519,8 @@ validering, node-opprettelse) ligger i synops-mail.
## 14. Verifisering etter oppsett
### Lag A (minimum fungerende server)
- [ ] `https://auth.sidelinja.org` viser Authentik login
- [ ] `https://git.sidelinja.org` viser Forgejo, innlogging via Authentik fungerer
- [ ] `https://auth.synops.no` viser Authentik login
- [ ] `https://git.synops.no` viser Forgejo, innlogging via Authentik fungerer
- [ ] PostgreSQL: `docker compose exec postgres pg_isready` returnerer OK
- [ ] Git push til Forgejo fungerer

View file

@ -110,12 +110,12 @@ pub async fn resolve_routing_or_default(db: &PgPool, job_type: &str) -> String {
alias
}
Ok(None) => {
tracing::warn!(job_type, "Ingen rutingregel — bruker sidelinja/rutine");
"sidelinja/rutine".to_string()
tracing::warn!(job_type, "Ingen rutingregel — bruker synops/low");
"synops/low".to_string()
}
Err(e) => {
tracing::error!(job_type, error = %e, "Feil ved oppslag i ai_job_routing — bruker fallback");
"sidelinja/rutine".to_string()
"synops/low".to_string()
}
}
}

View file

@ -12,7 +12,7 @@
// Flyten:
// 1. Hent kilde-node content fra PG
// 2. Hent AI-preset prompt + modellprofil fra PG
// 3. Map modellprofil → LiteLLM-alias (flash → sidelinja/rutine, standard → sidelinja/resonering)
// 3. Map modellprofil → LiteLLM-alias (flash → synops/low, standard → synops/high)
// 4. Send til AI Gateway (LiteLLM)
// 5. Logg forbruk i ai_usage_log
// 6. Direction-logikk:
@ -90,9 +90,9 @@ struct MessageContent {
/// Ref: docs/features/ai_verktoy.md § 4, docs/infra/ai_gateway.md § 3.4
fn model_profile_to_alias(profile: &str) -> &'static str {
match profile {
"flash" => "sidelinja/rutine",
"standard" => "sidelinja/resonering",
_ => "sidelinja/rutine", // fallback til billigste
"flash" => "synops/low",
"standard" => "synops/high",
_ => "synops/low", // fallback til billigste
}
}

View file

@ -211,8 +211,8 @@ pub fn start_bandwidth_parser(db: PgPool) {
// Kjør parsing for alle loggfiler
let log_files = vec![
"/var/log/caddy/access-sidelinja.log",
"/var/log/caddy/access-synops.log",
"/var/log/caddy/access-ws.log",
];
for path in &log_files {

View file

@ -147,7 +147,7 @@ async fn check_caddy() -> ServiceStatus {
async fn check_authentik() -> ServiceStatus {
// Authentik via Caddy
check_http_service("Authentik", "https://auth.sidelinja.org/-/health/ready/").await
check_http_service("Authentik", "https://auth.synops.no/-/health/ready/").await
}
async fn check_litellm() -> ServiceStatus {

View file

@ -3665,7 +3665,7 @@ pub async fn join_communication(
let livekit_url = std::env::var("LIVEKIT_WS_URL")
.unwrap_or_else(|_| {
// Fallback: bruk domene med wss
"wss://sidelinja.org/livekit".to_string()
"wss://ws.synops.no/livekit".to_string()
});
tracing::info!(

View file

@ -124,7 +124,7 @@ async fn main() {
// JWKS — hent nøkler fra Authentik ved oppstart
let issuer = std::env::var("AUTHENTIK_ISSUER")
.unwrap_or_else(|_| "https://auth.sidelinja.org/application/o/sidelinja/".to_string());
.unwrap_or_else(|_| "https://auth.synops.no/application/o/sidelinja/".to_string());
let client_id = std::env::var("AUTHENTIK_CLIENT_ID")
.expect("AUTHENTIK_CLIENT_ID må være satt");

View file

@ -19,14 +19,14 @@ Slettes når Synops er oppe og stabilt.
| ai-gateway | litellm:main-stable | AI-ruter | BEHOLDES (uavhengig av app) |
## Caddyfile (fungerende)
- auth.sidelinja.org → authentik-server:9000
- git.sidelinja.org → forgejo:3000
- sidelinja.org → web:3000 + /media/* (filservering) + JSON access log
- auth.synops.no → authentik-server:9000
- git.synops.no → forgejo:3000
- synops.no → web:3000 + /media/* (filservering) + JSON access log
- vegard.info → placeholder
- ~~rt.sidelinja.org → spacetimedb:3000~~ (fjernet)
- ~~rt.synops.no → spacetimedb:3000~~ (fjernet)
## PG init-script
`/srv/sidelinja/config/postgres/init/01-create-databases.sql`
`/srv/synops/config/postgres/init/01-create-databases.sql`
Oppretter authentik og forgejo DB-brukere med hardkodede passord.
Disse passordene matcher .env-variablene og er allerede kjørt — scriptet
kjøres kun ved *første* PG-oppstart.
@ -61,7 +61,7 @@ Synops starter med nytt skjema (noder+edges). Disse migreringene er irrelevante.
## Crontab
Ingen crontab konfigurert (backup-strategi er dokumentert men ikke implementert).
## Mappestruktur /srv/sidelinja/
## Mappestruktur /srv/synops/
```
config/authentik/ config/caddy/ config/postgres/init/
data/authentik/ data/caddy/ data/forgejo/ data/postgres/ data/redis/ data/spacetimedb/

View file

@ -36,7 +36,7 @@ struct PromptArgs {
#[arg(long)]
prompt: String,
/// Modellalias (f.eks. "sidelinja/rutine"). Hvis utelatt, slås opp fra ai_job_routing.
/// Modellalias (f.eks. "synops/low"). Hvis utelatt, slås opp fra ai_job_routing.
#[arg(long)]
model: Option<String>,
@ -486,7 +486,7 @@ async fn create_budget_work_item(
);
}
/// Slå opp modellalias fra ai_job_routing. Fallback: sidelinja/rutine.
/// Slå opp modellalias fra ai_job_routing. Fallback: synops/low.
async fn resolve_model(db: &sqlx::PgPool, job_type: &str) -> Result<String, String> {
let row: Option<(String,)> =
sqlx::query_as("SELECT alias FROM ai_job_routing WHERE job_type = $1")
@ -501,7 +501,7 @@ async fn resolve_model(db: &sqlx::PgPool, job_type: &str) -> Result<String, Stri
Ok(alias)
}
None => {
let fallback = "sidelinja/rutine".to_string();
let fallback = "synops/low".to_string();
tracing::info!(
job_type,
fallback = %fallback,
@ -778,7 +778,7 @@ async fn run_script(args: ScriptArgs) -> Result<(), String> {
tracing::info!(description_len = description.len(), "Sender til LLM for script-generering");
let model =
std::env::var("AI_SCRIPT_MODEL").unwrap_or_else(|_| "sidelinja/rutine".to_string());
std::env::var("AI_SCRIPT_MODEL").unwrap_or_else(|_| "synops/low".to_string());
let messages = vec![
ChatMessage {

View file

@ -91,6 +91,12 @@ dependencies = [
"num-traits",
]
[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "autocfg"
version = "1.5.0"
@ -161,6 +167,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cfg_aliases"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "chrono"
version = "0.4.44"
@ -498,8 +510,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi",
"wasm-bindgen",
]
[[package]]
name = "getrandom"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"r-efi 5.3.0",
"wasip2",
"wasm-bindgen",
]
[[package]]
@ -510,7 +538,7 @@ checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"r-efi 6.0.0",
"wasip2",
"wasip3",
]
@ -580,6 +608,106 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "http"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
dependencies = [
"bytes",
"itoa",
]
[[package]]
name = "http-body"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [
"bytes",
"http",
]
[[package]]
name = "http-body-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
dependencies = [
"bytes",
"futures-core",
"http",
"http-body",
"pin-project-lite",
]
[[package]]
name = "httparse"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
name = "hyper"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11"
dependencies = [
"atomic-waker",
"bytes",
"futures-channel",
"futures-core",
"http",
"http-body",
"httparse",
"itoa",
"pin-project-lite",
"pin-utils",
"smallvec",
"tokio",
"want",
]
[[package]]
name = "hyper-rustls"
version = "0.27.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
dependencies = [
"http",
"hyper",
"hyper-util",
"rustls",
"rustls-pki-types",
"tokio",
"tokio-rustls",
"tower-service",
"webpki-roots 1.0.6",
]
[[package]]
name = "hyper-util"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0"
dependencies = [
"base64",
"bytes",
"futures-channel",
"futures-util",
"http",
"http-body",
"hyper",
"ipnet",
"libc",
"percent-encoding",
"pin-project-lite",
"socket2",
"tokio",
"tower-service",
"tracing",
]
[[package]]
name = "iana-time-zone"
version = "0.1.65"
@ -733,6 +861,22 @@ dependencies = [
"serde_core",
]
[[package]]
name = "ipnet"
version = "2.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2"
[[package]]
name = "iri-string"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.2"
@ -825,6 +969,12 @@ version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "lru-slab"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
[[package]]
name = "matchers"
version = "0.2.0"
@ -881,7 +1031,7 @@ dependencies = [
"num-integer",
"num-iter",
"num-traits",
"rand",
"rand 0.8.5",
"smallvec",
"zeroize",
]
@ -978,6 +1128,12 @@ version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkcs1"
version = "0.7.5"
@ -1048,6 +1204,61 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "quinn"
version = "0.11.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
dependencies = [
"bytes",
"cfg_aliases",
"pin-project-lite",
"quinn-proto",
"quinn-udp",
"rustc-hash",
"rustls",
"socket2",
"thiserror 2.0.18",
"tokio",
"tracing",
"web-time",
]
[[package]]
name = "quinn-proto"
version = "0.11.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
dependencies = [
"bytes",
"getrandom 0.3.4",
"lru-slab",
"rand 0.9.2",
"ring",
"rustc-hash",
"rustls",
"rustls-pki-types",
"slab",
"thiserror 2.0.18",
"tinyvec",
"tracing",
"web-time",
]
[[package]]
name = "quinn-udp"
version = "0.5.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd"
dependencies = [
"cfg_aliases",
"libc",
"once_cell",
"socket2",
"tracing",
"windows-sys 0.52.0",
]
[[package]]
name = "quote"
version = "1.0.45"
@ -1057,6 +1268,12 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "r-efi"
version = "6.0.0"
@ -1070,8 +1287,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
]
[[package]]
name = "rand"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.5",
]
[[package]]
@ -1081,7 +1308,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core 0.9.5",
]
[[package]]
@ -1093,6 +1330,15 @@ dependencies = [
"getrandom 0.2.17",
]
[[package]]
name = "rand_core"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
dependencies = [
"getrandom 0.3.4",
]
[[package]]
name = "redox_syscall"
version = "0.5.18"
@ -1128,6 +1374,44 @@ version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
[[package]]
name = "reqwest"
version = "0.12.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
dependencies = [
"base64",
"bytes",
"futures-core",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-rustls",
"hyper-util",
"js-sys",
"log",
"percent-encoding",
"pin-project-lite",
"quinn",
"rustls",
"rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tokio-rustls",
"tower",
"tower-http",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"webpki-roots 1.0.6",
]
[[package]]
name = "ring"
version = "0.17.14"
@ -1155,13 +1439,19 @@ dependencies = [
"num-traits",
"pkcs1",
"pkcs8",
"rand_core",
"rand_core 0.6.4",
"signature",
"spki",
"subtle",
"zeroize",
]
[[package]]
name = "rustc-hash"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
[[package]]
name = "rustls"
version = "0.23.37"
@ -1182,6 +1472,7 @@ version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
dependencies = [
"web-time",
"zeroize",
]
@ -1329,7 +1620,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
"digest",
"rand_core",
"rand_core 0.6.4",
]
[[package]]
@ -1495,7 +1786,7 @@ dependencies = [
"memchr",
"once_cell",
"percent-encoding",
"rand",
"rand 0.8.5",
"rsa",
"serde",
"sha1",
@ -1535,7 +1826,7 @@ dependencies = [
"md-5",
"memchr",
"once_cell",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"sha2",
@ -1614,6 +1905,15 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "sync_wrapper"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
dependencies = [
"futures-core",
]
[[package]]
name = "synops-calendar"
version = "0.1.0"
@ -1621,6 +1921,7 @@ dependencies = [
"chrono",
"clap",
"ical",
"reqwest",
"serde",
"serde_json",
"sqlx",
@ -1759,6 +2060,16 @@ dependencies = [
"syn",
]
[[package]]
name = "tokio-rustls"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
dependencies = [
"rustls",
"tokio",
]
[[package]]
name = "tokio-stream"
version = "0.1.18"
@ -1770,6 +2081,51 @@ dependencies = [
"tokio",
]
[[package]]
name = "tower"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4"
dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper",
"tokio",
"tower-layer",
"tower-service",
]
[[package]]
name = "tower-http"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
dependencies = [
"bitflags",
"bytes",
"futures-util",
"http",
"http-body",
"iri-string",
"pin-project-lite",
"tower",
"tower-layer",
"tower-service",
]
[[package]]
name = "tower-layer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
[[package]]
name = "tower-service"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
[[package]]
name = "tracing"
version = "0.1.44"
@ -1832,6 +2188,12 @@ dependencies = [
"tracing-log",
]
[[package]]
name = "try-lock"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "typenum"
version = "1.19.0"
@ -1931,6 +2293,15 @@ version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "want"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
dependencies = [
"try-lock",
]
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
@ -1974,6 +2345,20 @@ dependencies = [
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8"
dependencies = [
"cfg-if",
"futures-util",
"js-sys",
"once_cell",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.114"
@ -2040,6 +2425,26 @@ dependencies = [
"semver",
]
[[package]]
name = "web-sys"
version = "0.3.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "web-time"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "webpki-roots"
version = "0.26.11"

2941
tools/synops-clip/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -19,7 +19,7 @@
// DATABASE_URL — PostgreSQL-tilkobling (påkrevd med --write)
// AI_GATEWAY_URL — LiteLLM gateway (default: http://localhost:4000)
// LITELLM_MASTER_KEY — API-nøkkel for LiteLLM
// AI_CLIP_MODEL — Modellalias for oppsummering (default: sidelinja/rutine)
// AI_CLIP_MODEL — Modellalias for oppsummering (default: synops/low)
// RUST_LOG — Loggnivå (default: synops_clip=info)
//
// Ref: docs/retninger/unix_filosofi.md
@ -462,7 +462,7 @@ async fn call_llm_analysis(
std::env::var("AI_GATEWAY_URL").unwrap_or_else(|_| "http://localhost:4000".to_string());
let api_key = std::env::var("LITELLM_MASTER_KEY").unwrap_or_default();
let model =
std::env::var("AI_CLIP_MODEL").unwrap_or_else(|_| "sidelinja/rutine".to_string());
std::env::var("AI_CLIP_MODEL").unwrap_or_else(|_| "synops/low".to_string());
// Hent eksisterende topics for kontekst
let existing_topics = sqlx::query_scalar::<_, String>(

3000
tools/synops-health/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

2449
tools/synops-notify/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

2463
tools/synops-stats/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -8,7 +8,7 @@
// DATABASE_URL — PostgreSQL-tilkobling (påkrevd)
// AI_GATEWAY_URL — LiteLLM gateway (default: http://localhost:4000)
// LITELLM_MASTER_KEY — API-nøkkel for LiteLLM
// AI_EDGES_MODEL — Modellalias (default: sidelinja/rutine)
// AI_EDGES_MODEL — Modellalias (default: synops/low)
//
// Erstatter: maskinrommet/src/ai_edges.rs
// Ref: docs/retninger/unix_filosofi.md, docs/infra/ai_gateway.md,
@ -317,7 +317,7 @@ async fn call_llm(user_content: &str) -> Result<(AiSuggestion, Option<UsageInfo>
let api_key = std::env::var("LITELLM_MASTER_KEY").unwrap_or_default();
let model =
std::env::var("AI_EDGES_MODEL").unwrap_or_else(|_| "sidelinja/rutine".to_string());
std::env::var("AI_EDGES_MODEL").unwrap_or_else(|_| "synops/low".to_string());
let request = ChatRequest {
model,

View file

@ -8,7 +8,7 @@
// DATABASE_URL — PostgreSQL-tilkobling (påkrevd)
// AI_GATEWAY_URL — LiteLLM gateway (default: http://localhost:4000)
// LITELLM_MASTER_KEY — API-nøkkel for LiteLLM
// AI_SUMMARY_MODEL — Modellalias (default: sidelinja/rutine)
// AI_SUMMARY_MODEL — Modellalias (default: synops/low)
//
// Erstatter: maskinrommet/src/summarize.rs
// Ref: docs/retninger/unix_filosofi.md, docs/infra/ai_gateway.md
@ -292,7 +292,7 @@ async fn call_llm_summary(
let api_key = std::env::var("LITELLM_MASTER_KEY").unwrap_or_default();
let model =
std::env::var("AI_SUMMARY_MODEL").unwrap_or_else(|_| "sidelinja/rutine".to_string());
std::env::var("AI_SUMMARY_MODEL").unwrap_or_else(|_| "synops/low".to_string());
let request = ChatRequest {
model,