initial commit: rocket.new export of broadcastbeat

This commit is contained in:
Ryan Salazar
2026-05-07 16:39:17 +00:00
commit 70aa1ad46e
302 changed files with 60710 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
import { NextRequest, NextResponse } from 'next/server';
import { hybridAI } from '@/lib/ai/hybridRouter';
import { sampleArticles } from '@/lib/articles/sampleArticles';
export async function POST(request: NextRequest) {
try {
const { interests, readingHistory } = await request.json();
// Build a compact article index for the AI to reason over
const articleIndex = sampleArticles
.filter((a) => a.section === 'news')
.map((a) => ({
slug: a.slug,
title: a.title,
excerpt: a.excerpt,
tags: a.tags,
category: a.category,
date: a.date,
}));
const systemPrompt = `You are a personalized content recommendation engine for BroadcastBeat, a broadcast engineering news platform.
Given a reader's topic interests and reading history, select the 4 most relevant articles from the provided article list.
Return ONLY a valid JSON array of slugs in order of relevance. Example: ["slug-1","slug-2","slug-3","slug-4"]
Do not include any explanation or markdown — only the raw JSON array.`;
const userPrompt = `Reader interests: ${interests?.length ? interests.join(', ') : 'general broadcast engineering'}
Reading history (recently read slugs): ${readingHistory?.length ? readingHistory.join(', ') : 'none'}
Available articles:
${JSON.stringify(articleIndex, null, 2)}
Return the 4 most relevant article slugs as a JSON array.`;
const result = await hybridAI(
[
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt },
],
{
maxTokens: 200,
temperature: 0.3,
priority: 4,
}
);
const content = result.text;
let slugs: string[] = [];
try {
// Extract JSON array from response (model may wrap it in text)
const match = content.match(/\[[\s\S]*?\]/);
slugs = match ? JSON.parse(match[0]) : JSON.parse(content.trim());
} catch {
// Fallback: extract slugs with regex
const matches = content.match(/"([^"]+)"/g);
slugs = matches ? matches.map((m: string) => m.replace(/"/g, '')).slice(0, 4) : [];
}
// Resolve full article objects
const suggested = slugs
.map((slug: string) => sampleArticles.find((a) => a.slug === slug))
.filter(Boolean)
.slice(0, 4);
// Fallback: return latest news if AI returned nothing useful
if (suggested.length === 0) {
const fallback = sampleArticles
.filter((a) => a.section === 'news')
.slice(0, 4);
return NextResponse.json({ suggestions: fallback });
}
return NextResponse.json({ suggestions: suggested });
} catch (error) {
console.error('Article suggestions error:', error);
// Graceful fallback
const fallback = sampleArticles.filter((a) => a.section === 'news').slice(0, 4);
return NextResponse.json({ suggestions: fallback });
}
}