ai: implement ollama rewrite provider + ryan-salazar byline default
The press-release rewriter (ai_rewrite_jobs) was stuck because: - BB_REWRITE_PROVIDER defaulted to "anthropic" in code, AND - production env still had BB_REWRITE_PROVIDER=anthropic, AND - ollamaProvider.rewrite() was a stub that threw "not implemented". Every job since 2026-01-26 hit Anthropic 400 "credit balance too low" — 12 failed_api in a row. Changes: - Implement ollamaProvider against /v1/chat/completions on the local Ollama (works against AI_001:11434 / llama3.1:70b). Same JSON contract as the Anthropic provider; gets prompt_tokens / completion_tokens out of Ollama's usage block. - Flip the default provider from "anthropic" → "ollama" in getProvider(), so the rewriter works out of the box now that the Ollama implementation exists. - Make the BB auto-story byline configurable via env. Default flips from a 12-name pen rotation to a single "Ryan Salazar" byline for Broadcast Beat (per editorial directive). AV Beat keeps its own pen pool. Set BB_AUTOSTORY_BYLINE=rotate to restore the old behaviour. Production env still needs (set in Coolify dashboard): OLLAMA_ENDPOINT=http://10.10.0.66:11434 OLLAMA_MODEL_DEFAULT=llama3.1:70b BB_REWRITE_PROVIDER=ollama BB_REWRITE_MODEL=llama3.1:70b (remove ANTHROPIC_API_KEY)
This commit is contained in:
@@ -3,19 +3,33 @@ import { createClient } from '@/lib/supabase/server';
|
||||
import { createAdminClient } from '@/lib/supabase/admin';
|
||||
import { hybridAI } from '@/lib/ai/hybridRouter';
|
||||
|
||||
// ─── Pen name rotation ────────────────────────────────────────────────────────
|
||||
const BB_PEN_NAMES = [
|
||||
// ─── Byline ───────────────────────────────────────────────────────────────────
|
||||
// All auto-generated BB stories publish under Ryan Salazar's byline (founder).
|
||||
// AV Beat retains its own pen pool. To re-enable the BB rotation, set
|
||||
// BB_AUTOSTORY_BYLINE="rotate" — env override so we don't need a code change
|
||||
// when the editorial policy changes.
|
||||
const AV_PEN_NAMES = ['Rex Chandler', 'Dana Flux', 'Derek Wainwright', 'Sloane Rigging', 'Chip Crosspoint', 'Blair Presenter', 'Jordan Lumen'];
|
||||
const BB_PEN_NAMES_LEGACY = [
|
||||
'Michael Strand', 'David Harlow', 'Karen Fielding', 'James Mercer',
|
||||
'Peter Calloway', 'Sandra Voss', 'Brian Kowalski', 'Laura Pennington',
|
||||
'Thomas Reeves', 'Christine Vale', 'Marcus Webb', 'Ellen Forsythe',
|
||||
];
|
||||
const AV_PEN_NAMES = ['Rex Chandler', 'Dana Flux', 'Derek Wainwright', 'Sloane Rigging', 'Chip Crosspoint', 'Blair Presenter', 'Jordan Lumen'];
|
||||
const BB_AUTOSTORY_BYLINE = process.env.BB_AUTOSTORY_BYLINE || 'Ryan Salazar';
|
||||
|
||||
function pickPenName(siteId: number, recentNames: string[]): string {
|
||||
const pool = siteId === 2 ? AV_PEN_NAMES : BB_PEN_NAMES;
|
||||
// Avoid last 3 used names
|
||||
const available = pool.filter(n => !recentNames.slice(-3).includes(n));
|
||||
return available[Math.floor(Math.random() * available.length)] || pool[0];
|
||||
// AV Beat: rotate its small pen pool
|
||||
if (siteId === 2) {
|
||||
const pool = AV_PEN_NAMES;
|
||||
const available = pool.filter(n => !recentNames.slice(-3).includes(n));
|
||||
return available[Math.floor(Math.random() * available.length)] || pool[0];
|
||||
}
|
||||
// Broadcast Beat: fixed byline (Ryan) unless overridden to "rotate".
|
||||
if (BB_AUTOSTORY_BYLINE.toLowerCase() === 'rotate') {
|
||||
const pool = BB_PEN_NAMES_LEGACY;
|
||||
const available = pool.filter(n => !recentNames.slice(-3).includes(n));
|
||||
return available[Math.floor(Math.random() * available.length)] || pool[0];
|
||||
}
|
||||
return BB_AUTOSTORY_BYLINE;
|
||||
}
|
||||
|
||||
// ─── Company extraction via Hybrid AI ────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user