- 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>
78 lines
3.8 KiB
PL/PgSQL
78 lines
3.8 KiB
PL/PgSQL
-- 0007_ai_config.sql
|
|
-- AI-administrasjon: modellaliaser, leverandører, jobbruting og tokenlogging.
|
|
-- PG som source of truth for LiteLLM config-generering.
|
|
|
|
BEGIN;
|
|
|
|
-- === Modellaliaser (globale, ikke per workspace) ===
|
|
CREATE TABLE ai_model_aliases (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
alias TEXT NOT NULL UNIQUE, -- f.eks. "sidelinja/rutine"
|
|
description TEXT, -- kort beskrivelse av aliaset
|
|
is_active BOOLEAN NOT NULL DEFAULT true,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- === Leverandør-modeller per alias med prioritet ===
|
|
CREATE TABLE ai_model_providers (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
alias_id UUID NOT NULL REFERENCES ai_model_aliases(id) ON DELETE CASCADE,
|
|
priority INT NOT NULL DEFAULT 1, -- lavere = høyere prioritet i LiteLLM
|
|
litellm_model TEXT NOT NULL, -- f.eks. "gemini/gemini-2.5-flash-lite"
|
|
api_key_env TEXT NOT NULL, -- f.eks. "GEMINI_API_KEY"
|
|
is_active BOOLEAN NOT NULL DEFAULT true,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
UNIQUE (alias_id, priority)
|
|
);
|
|
|
|
-- === Jobbtype → alias mapping ===
|
|
CREATE TABLE ai_job_routing (
|
|
job_type TEXT PRIMARY KEY, -- f.eks. "ai_text_process"
|
|
alias_id UUID NOT NULL REFERENCES ai_model_aliases(id) ON DELETE RESTRICT,
|
|
description TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- === Per-kall token-logging (workspace-scopet) ===
|
|
CREATE TABLE ai_usage_log (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
job_id UUID REFERENCES job_queue(id) ON DELETE SET NULL,
|
|
job_type TEXT NOT NULL,
|
|
model_alias TEXT NOT NULL, -- alias brukt (snapshot)
|
|
model_actual TEXT, -- faktisk modell fra respons
|
|
prompt_tokens INT NOT NULL DEFAULT 0,
|
|
completion_tokens INT NOT NULL DEFAULT 0,
|
|
total_tokens INT NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_ai_usage_log_workspace ON ai_usage_log (workspace_id, created_at DESC);
|
|
CREATE INDEX idx_ai_usage_log_alias ON ai_usage_log (model_alias, created_at DESC);
|
|
|
|
-- === Seed-data: matcher nåværende config.yaml ===
|
|
|
|
-- Aliaser
|
|
INSERT INTO ai_model_aliases (alias, description) VALUES
|
|
('sidelinja/rutine', 'Billig, høyt volum — tekstrensing, faktauthenting, oversettelse'),
|
|
('sidelinja/resonering', 'Presis, lav volum — kompleks analyse, research');
|
|
|
|
-- Leverandører for sidelinja/rutine
|
|
INSERT INTO ai_model_providers (alias_id, priority, litellm_model, api_key_env) VALUES
|
|
((SELECT id FROM ai_model_aliases WHERE alias = 'sidelinja/rutine'), 1, 'gemini/gemini-2.5-flash-lite', 'GEMINI_API_KEY'),
|
|
((SELECT id FROM ai_model_aliases WHERE alias = 'sidelinja/rutine'), 2, 'gemini/gemini-2.5-flash', 'GEMINI_API_KEY'),
|
|
((SELECT id FROM ai_model_aliases WHERE alias = 'sidelinja/rutine'), 3, 'openrouter/google/gemini-2.5-flash-preview', 'OPENROUTER_API_KEY');
|
|
|
|
-- Leverandører for sidelinja/resonering
|
|
INSERT INTO ai_model_providers (alias_id, priority, litellm_model, api_key_env) VALUES
|
|
((SELECT id FROM ai_model_aliases WHERE alias = 'sidelinja/resonering'), 1, 'openrouter/anthropic/claude-sonnet-4', 'OPENROUTER_API_KEY'),
|
|
((SELECT id FROM ai_model_aliases WHERE alias = 'sidelinja/resonering'), 2, 'gemini/gemini-2.5-flash', 'GEMINI_API_KEY');
|
|
|
|
-- Jobbruting
|
|
INSERT INTO ai_job_routing (job_type, alias_id, description) VALUES
|
|
('ai_text_process', (SELECT id FROM ai_model_aliases WHERE alias = 'sidelinja/rutine'), 'Tekstrensing og AI-behandling via ✨-knappen');
|
|
|
|
COMMIT;
|