62 lines
1.7 KiB
TypeScript
62 lines
1.7 KiB
TypeScript
/**
|
|
* Polderfest 2027 — chat API route
|
|
* --------------------------------------------------
|
|
* Les 11 — Vercel AI SDK + Supabase context.
|
|
* Plaats dit bestand op: app/api/chat/route.ts
|
|
*
|
|
* Werking:
|
|
* 1. Haal alle bands op uit Supabase
|
|
* 2. Formatteer als tekst-context
|
|
* 3. Stuur naar OpenAI via streamText + system prompt
|
|
* 4. Return een stream voor useChat
|
|
*
|
|
* Vereist:
|
|
* - NEXT_PUBLIC_SUPABASE_URL en NEXT_PUBLIC_SUPABASE_ANON_KEY in .env.local
|
|
* - OPENAI_API_KEY in .env.local
|
|
* - npm i ai @ai-sdk/openai @supabase/supabase-js
|
|
*/
|
|
|
|
import { streamText } from "ai";
|
|
import { openai } from "@ai-sdk/openai";
|
|
import { createClient } from "@supabase/supabase-js";
|
|
|
|
const supabase = createClient(
|
|
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
);
|
|
|
|
export async function POST(req: Request) {
|
|
const { messages } = await req.json();
|
|
|
|
// 1. Haal alle bands op uit Supabase
|
|
const { data: bands, error } = await supabase.from("bands").select("*");
|
|
if (error) throw error;
|
|
|
|
// 2. Format bands als context-string
|
|
const context = bands!
|
|
.map(
|
|
(b) =>
|
|
`- ${b.name} (${b.genre}, ${b.tier}, ${b.day} ${b.start_time} ` +
|
|
`op ${b.stage}, uit ${b.origin_city})`,
|
|
)
|
|
.join("\n");
|
|
|
|
// 3. System prompt met context
|
|
const system = `Je bent een festival-assistent voor Polderfest 2027.
|
|
Hier zijn alle bands die op het festival spelen:
|
|
|
|
${context}
|
|
|
|
Beantwoord vragen van bezoekers over de line-up. Verzin niets — gebruik
|
|
alleen bovenstaande data. Antwoord in het Nederlands. Wees beknopt.`;
|
|
|
|
// 4. Stream naar OpenAI
|
|
const result = streamText({
|
|
model: openai("gpt-4o-mini"),
|
|
system,
|
|
messages,
|
|
});
|
|
|
|
return result.toDataStreamResponse();
|
|
}
|