Worker: slå opp modellalias fra ai_job_routing i stedet for hardkodet default

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>
This commit is contained in:
vegard 2026-03-16 07:16:18 +01:00
parent b0d0202eb8
commit 1f25c50d50

View file

@ -80,15 +80,26 @@ impl JobHandler for AiTextProcessHandler {
let prompt_override = payload.get("prompt_override").and_then(|v| v.as_str()); let prompt_override = payload.get("prompt_override").and_then(|v| v.as_str());
// Slå opp modellalias fra jobbrutingen, fall tilbake til payload eller default
let model_from_routing: Option<String> = sqlx::query_scalar(
"SELECT a.alias FROM ai_job_routing r JOIN ai_model_aliases a ON a.id = r.alias_id WHERE r.job_type = 'ai_text_process'"
)
.fetch_optional(pool)
.await
.ok()
.flatten();
let model = payload let model = payload
.get("model") .get("model")
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
.unwrap_or("sidelinja/rutine"); .map(|s| s.to_string())
.or(model_from_routing)
.unwrap_or_else(|| "sidelinja/rutine".to_string());
info!( info!(
message_id = %message_id, message_id = %message_id,
action = action, action = action,
model = model, model = %model,
workspace_id = %workspace_id, workspace_id = %workspace_id,
"AI-behandling starter" "AI-behandling starter"
); );
@ -146,12 +157,12 @@ impl JobHandler for AiTextProcessHandler {
// 4. Bygg system-prompt basert på action // 4. Bygg system-prompt basert på action
let system_prompt = match prompt_override { let system_prompt = match prompt_override {
Some(custom) => custom.to_string(), Some(custom) => custom.to_string(),
None => get_system_prompt(action), None => get_system_prompt_from_db(pool, action).await,
}; };
// 5. Send til AI Gateway // 5. Send til AI Gateway
let ai_resp = self let ai_resp = self
.call_ai_gateway(&system_prompt, &plain_text, model) .call_ai_gateway(&system_prompt, &plain_text, &model)
.await .await
.context("AI Gateway-kall feilet")?; .context("AI Gateway-kall feilet")?;
@ -322,9 +333,29 @@ impl AiTextProcessHandler {
} }
} }
fn get_system_prompt(action: &str) -> String { /// Hent system-prompt fra ai_prompts-tabellen, med fallback til hardkodet prompt.
async fn get_system_prompt_from_db(pool: &PgPool, action: &str) -> String {
match sqlx::query_scalar::<_, String>("SELECT system_prompt FROM ai_prompts WHERE action = $1")
.bind(action)
.fetch_optional(pool)
.await
{
Ok(Some(prompt)) => prompt,
Ok(None) => {
warn!(action = action, "Ingen prompt funnet i DB, bruker fallback");
get_system_prompt_fallback(action)
}
Err(e) => {
warn!(action = action, error = %e, "Feil ved henting av prompt fra DB, bruker fallback");
get_system_prompt_fallback(action)
}
}
}
fn get_system_prompt_fallback(action: &str) -> String {
match action { match action {
"fix_text" => r#"Fiks denne teksten. Output på norsk. "fix_text" => r#"Fiks denne teksten. Output på norsk.
- Returner KUN den fiksede teksten ingen innledning, kommentar eller meta-tekst
- Fiks skrivefeil og grammatikk - Fiks skrivefeil og grammatikk
- Start med en kort oppsummering av det viktigste (23 setninger) - Start med en kort oppsummering av det viktigste (23 setninger)
- Fjern metainformasjon, navigasjon, annonser og annen støy fra innlimt webinnhold - Fjern metainformasjon, navigasjon, annonser og annen støy fra innlimt webinnhold
@ -334,6 +365,7 @@ fn get_system_prompt(action: &str) -> String {
.to_string(), .to_string(),
"extract_facts" => r#"Analyser denne teksten og trekk ut fakta. Output på norsk. "extract_facts" => r#"Analyser denne teksten og trekk ut fakta. Output på norsk.
- Returner KUN faktalisten ingen innledning, kommentar eller meta-tekst
- Identifiser konkrete påstander, tall, sitater og fakta - Identifiser konkrete påstander, tall, sitater og fakta
- List dem opp som punktliste - List dem opp som punktliste
- For hver fakta: noter hvilken person eller organisasjon den gjelder (bruk #Navn-format) - For hver fakta: noter hvilken person eller organisasjon den gjelder (bruk #Navn-format)
@ -342,6 +374,7 @@ fn get_system_prompt(action: &str) -> String {
.to_string(), .to_string(),
"rewrite" => r#"Skriv om denne teksten til artikkelformat. Output på norsk. "rewrite" => r#"Skriv om denne teksten til artikkelformat. Output på norsk.
- Returner KUN artikkelen ingen innledning, kommentar eller meta-tekst
- Lag en tittel som fanger essensen - Lag en tittel som fanger essensen
- Skriv en ingress 23 setninger - Skriv en ingress 23 setninger
- Strukturer resten med mellomtitler der det er naturlig - Strukturer resten med mellomtitler der det er naturlig
@ -350,6 +383,7 @@ fn get_system_prompt(action: &str) -> String {
.to_string(), .to_string(),
"translate" => r#"Oversett denne teksten til norsk. "translate" => r#"Oversett denne teksten til norsk.
- Returner KUN oversettelsen ingen innledning, kommentar eller meta-tekst
- Behold formatering og struktur - Behold formatering og struktur
- Oversett fagtermer korrekt, behold engelske termer i parentes der det er vanlig - Oversett fagtermer korrekt, behold engelske termer i parentes der det er vanlig
- Behold egennavn uoversatt"# - Behold egennavn uoversatt"#