Bakes inn i frontend ved build-time slik at chat bruker
SpacetimeDB-adapter i stedet for PG-polling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Frontend bruker PG-polling i prod (VITE_SPACETIMEDB_URL ikke satt).
Meldinger finnes bare i PG, ikke i SpacetimeDB — worker feilet ved
STDB-oppdatering og fullførte aldri jobben.
Nå: STDB-oppdatering er best-effort (warn ved feil), PG body
oppdateres alltid direkte som fallback.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- rebuildMessages bevarer nå PG-felter (metadata, edited_at, reply_count)
fra eksisterende meldinger i stedet for å overskrive med undefined
- Worker setter edited_at = now() ved AI-behandling slik at
revisjonshistorikk og AI-badge vises umiddelbart
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rediger-knappen i prompt-seksjonen fungerer som Avbryt når editoren er åpen
- Fjernet separat Avbryt-knapp fra prompt-editor footer
- pollJob sjekker nå også 'error'-status (ikke bare completed/failed)
- Worker rydder ai_processing-flagget fra metadata ved feil
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
docker CLI finnes ikke i web-containeren. Bruker http.request mot
/var/run/docker.sock i stedet for execSync('docker restart ...').
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- CLAUDE.md: lagt til standard arbeidsmodus, testmiljø og browser-testing
- ai_gateway.md: PG-eier-config arkitektur, datamodell, config-generering, admin-panel
- chat.md: trådvisning, meldingskollaps, AI-behandling, konvertering
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Dokumentert at subscriptions ikke støtter JOINs (feiler stille)
- refresh() kaller enrichFromPg() for å hente fersk metadata fra PG
- Whitespace-normalisering i autogenererte module_bindings
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Editor compact mode: send/minimer-knapper flyttes til bunnrad når utvidet
- KanbanBlock: bruker Editor-komponent for beskrivelse i stedet for textarea
- ConvertDialog: «Opprett» i stedet for «Konverter» (meldingen beholdes)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Messages API returnerer metadata-felt (ai_action, ai_label, ai_model)
- AI-badge i MessageBox viser label og faktisk modellnavn
- Reaksjoner: slett eksisterende før insert (én reaksjon per bruker per melding)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Modellkatalog henter fra xAI, Gemini, OpenAI og OpenRouter (ikke bare OR)
- Hver katalogmodell bærer litellm_prefix og api_key_env — forenkler add-flow
- Prompts har nå label, icon og sort_order — vises i chat og admin
- ai_usage_log får action-kolonne for å spore hvilken prompt som ble brukt
- Worker skriver PG-metadata FØR SpacetimeDB slik at frontend finner fersk data
- getUserWorkspaces returnerer rolle
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Worker slår opp faktisk modellnavn (f.eks. google/gemini-2.5-flash-lite)
fra providers-tabellen og lagrer det i model_actual
- Stripper openrouter/gemini-prefiks for lesbarhet
- Tokenforbruk-tabellen bruker faste kolonnebredder for korrekt justering
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ✨-knappen åpner nå en meny med tilgjengelige prompts (vask, sammendrag, skriv om, oversett)
- Prompts er workspace-konfigurerte via ny tabell workspace_ai_prompts
- Nytt API GET /api/ai/prompts returnerer tilgjengelige prompts for workspace
- AI-badge viser prompt-label og ikon i stedet for rå action-navn
- ai_prompts utvidet med label, icon og sort_order kolonner
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
process.cwd() i SvelteKit er web/, men config.yaml skal ligge i
prosjektrotens config/litellm/. Endret til relativ sti opp én mappe.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fjerner hardkodet «sidelinja/rutine» — henter alias dynamisk fra
ai_job_routing-tabellen slik at endringer i admin-grensesnittet
(alias-rename, ny ruting) fungerer uten å endre worker-kode.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fjernet UNIQUE(alias_id, priority) — prioritet er kun for sortering
- Forenklet swap-endpoint til to rene UPDATE-statements
- Renummerert kjapp-providers til sekvensielle prioriteter
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- «Legg til»-formen vises nå som egen rad under modellen med grønn kant
- Alias + nøkkel-dropdowns og bekreft-knapp har god plass
- Erstatter den sammenpressede inline-formen som ble klippet i smal kolonne
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Ny mapping fra OpenRouter-provider til LiteLLM direkte-prefiks
(google→gemini/, anthropic→anthropic/, openai→openai/, x-ai→xai/)
- «Legg til»-knappen i katalogen viser nå to dropdowns: alias + nøkkel
- Velger du Google-nøkkel → gemini/modellnavn, OpenRouter → openrouter/google/modellnavn
- Inline picker respekterer også valgt nøkkel i provider-skjemaet
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Nytt swap-endpoint (POST /api/admin/ai/providers/swap) for atomisk bytte
- Pil opp/ned ved hver provider-rad for å endre fallback-rekkefølge
- Prioritet avgjør hvilken modell LiteLLM prøver først per alias
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Nøkkelverdier kan lagres i DB (key_value) og brukes direkte i config
- Ny nøkkel-seksjon: legg til, rediger, slett API-nøkler fra UI
- Config-generering bruker DB-verdi hvis satt, ellers env-referanse
- Dynamisk api_key_env-dropdown basert på registrerte nøkler
- Gemini omdøpt til Google, OpenAI lagt til
- Slett-beskyttelse: kan ikke fjerne nøkkel som er i bruk av providers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Ny tabell ai_api_keys med is_enabled per nøkkel (GEMINI, OPENROUTER, etc.)
- Nøkkel-pills i toppen er nå klikkbare toggles (grønn=på, grå=av, rød=mangler)
- Config-generering filtrerer ut providers med deaktivert nøkkel
- Provider-rader viser visuelt når nøkkelen er slått av (rød kant + dimmet)
- Gjeldende modell per alias respekterer nøkkel-status
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Viser primærmodell (høyest prioritet, aktiv) under hvert alias-navn
- Migrerer alle gemini/-providers til openrouter/google/-ekvivalenter
- Endrer standard API-nøkkel i ny-provider-skjema til OPENROUTER_API_KEY
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Ny kolonne extra_params JSONB på ai_model_providers (migrasjon 0009)
- Web-søk toggle-pill per provider — ett klikk for å slå på/av
- «...»-knapp åpner JSON-editor for vilkårlige extra_params
- Config-generering fletter extra_params inn i litellm_params
- POST/PATCH provider-endepunkter støtter extra_params
Eksempel: Grok med web-plugin genererer:
plugins: [{"id":"web"}]
under litellm_params i config.yaml.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- PATCH /aliases/:id støtter nå rename (alias-felt)
- Alias-raden har «Rediger»-knapp → inline-redigering av navn + beskrivelse
- Tokenforbruk viser model_actual og estimert dollarkostnad per rad
- Dollarkostnad beregnes fra OpenRouter-katalogpriser (krever lastet katalog)
- Tokenforbruk-tabellen bruker auto-kolonnebredde (fikser overflow)
- «Kompl.» i stedet for «Completion» i header
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Utvider generate-config endepunktet med ?restart=true som finner
og restarter ai-gateway docker-containeren etter config-generering.
Ny grønn knapp i UI gjør begge operasjoner i ett klikk.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Nytt endepunkt /api/admin/ai/models som proxyer OpenRouter med 1t cache
- Nytt endepunkt /api/admin/ai/keys for API-nøkkelstatus
- API-nøkkel-pills (GEMINI/OPENROUTER/ANTHROPIC/XAI) øverst på siden
- Browsbar modellkatalog gruppert per leverandør i trekkspill-format
- Globalt søkefelt, sortert synkende etter pris per leverandør
- "Legg til →" fra katalog velger alias og oppretter provider
- Katalog-picker i eksisterende add-provider-form
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Server-admin (/server-admin): systemvide innstillinger (AI, kanaler) — kun for owners.
Workspace-admin (/admin): workspace-spesifikke innstillinger (sider, entiteter) — for owner/admin i gjeldende workspace.
- Ny rute /server-admin med egen layout-gate (owner-rolle)
- Flytt AI og kanaler fra /admin til /server-admin
- Workspace-admin gate sjekker nå rolle i gjeldende workspace
- Sidebar: workspace-admin-lenker under separator, server-admin-nav i server-admin-modus
- WorkspaceSwitcher: "Admin (server)" kun for owners
- Kanaler: trekkspill gruppert etter workspace
- Config-API: owners kan endre kanaler på tvers av workspaces
- Migrasjon: ai_prompts-tabell
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Før: worker skrev body til både PG og SpacetimeDB (dobbelt-skriving),
og sync.rs skrev den samme endringen tilbake fra SpacetimeDB til PG.
Nå: worker skriver body-endring KUN til SpacetimeDB, sync.rs synker
til PG som vanlig. Worker skriver kun PG-only data direkte (metadata,
revisjoner, tokenforbruk).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Etter onUpdate fra SpacetimeDB hentes edited_at og metadata
(ai_processed, ai_action) fra PG, slik at revisjonshistorikk
og AI-badge vises korrekt også for sanntidsoppdateringer.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
edit_message reducer forventer workspace_id og new_body,
ikke workspaceId og newBody. TypeScript SDK bruker camelCase,
men HTTP API-et bruker snake_case.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SpacetimeDB har ikke edited_at eller metadata-felter, så «redigert»-
indikatoren dukket aldri opp. Etter initial subscription-load gjør
frontend nå et kall til /api/channels/:id/messages/metadata for å
hente redigeringsstatus og AI-metadata fra PG.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Markdown rendres automatisk for all ikke-HTML body (detekterer <p>, <div> osv.)
- «redigert»-indikator med bla-navigasjon (← →) for alle redigerte meldinger
- Henter revisjoner fra PG via /api/messages/:id/revisions ved behov
- SpacetimeDB onUpdate setter edited_at slik at frontend vet meldingen er redigert
- AI-badge (✨ action) vises fortsatt for AI-behandlede meldinger
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- AI-resultat (markdown) rendres med marked-biblioteket
- «Vis original» / «Vis AI-resultat» toggle under AI-behandlede meldinger
- Nytt API: GET /api/messages/:id/revisions for å hente originaltekst
- Markdown-stiler: overskrifter, lister, blockquotes, kodeblokker
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Frontend leser fra SpacetimeDB, men workeren skrev kun til PG.
Nå kalles edit_message-reduceren i SpacetimeDB etter vellykket
AI-behandling, slik at resultatet vises umiddelbart i chatten.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Uten nøkkelen returnerte LiteLLM 401, og AI-jobber feilet etter 3 forsøk.
Ny CLI-param --ai-gateway-key (env: AI_GATEWAY_KEY). dev.sh leser
LITELLM_MASTER_KEY fra .env.local og eksporterer som AI_GATEWAY_KEY.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
JSON.stringify + ::jsonb via postgres-biblioteket lagret payload som
dobbelt-escaped string i stedet for JSONB-objekt. Workeren fant ikke
message_id i den resulterende strengen.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Migrasjon 0007: ai_model_aliases, ai_model_providers, ai_job_routing, ai_usage_log
- Worker: token-logging fra AI Gateway-respons til ai_usage_log
- Config-generering: POST /api/admin/ai/generate-config bygger config.yaml fra PG
- Admin-panel /admin/ai: aliaser, leverandører, jobbruting, tokenforbruk
- CRUD API for aliaser, providers og routing
- Workspace-forbruk API: GET /api/ai/usage?days=30
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
messages-modus: hent de N nyeste trådene (sortert etter siste
aktivitet), inkludert alle svar. Ingen orphan-replies.
days-modus: finn alle tråder med minst én melding innenfor
tidsvinduet, last hele tråden (også eldre trådstartere).
all-modus: uendret, henter alt.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>