92 lines
3.0 KiB
JavaScript
92 lines
3.0 KiB
JavaScript
import { anthropicApi } from './api';
|
|
import { storage } from './storage';
|
|
|
|
const CONTENT_GENERATION_SYSTEM = `Je bent een expert leerinhoud-schrijver voor Respellion, een intern IT-bedrijf.
|
|
Je schrijft leermateriaal voor medewerkers op basis van kennisonderwerpen.
|
|
Schrijf altijd in het Nederlands, helder en professioneel.
|
|
Geef ALTIJD geldige JSON terug, zonder markdown code-blokken.`;
|
|
|
|
/**
|
|
* Get the assigned topic for a user for a given week using round-robin.
|
|
* hash(userId + weekNumber) % topicCount
|
|
*/
|
|
export function getAssignedTopic(userId, weekNumber) {
|
|
const topics = storage.get('kb:topics', []);
|
|
if (!topics || topics.length === 0) return null;
|
|
|
|
// Simple deterministic hash
|
|
const str = `${userId}:${weekNumber}`;
|
|
let hash = 0;
|
|
for (let i = 0; i < str.length; i++) {
|
|
hash = (hash << 5) - hash + str.charCodeAt(i);
|
|
hash |= 0; // Convert to 32-bit integer
|
|
}
|
|
const index = Math.abs(hash) % topics.length;
|
|
return topics[index];
|
|
}
|
|
|
|
/**
|
|
* Generate a complete learning module for a topic.
|
|
* Returns an object with { article, slides, podcastScript, infographic }.
|
|
* Caches results in storage.
|
|
*/
|
|
export async function generateLearningContent(topic) {
|
|
const cacheKey = `kb:content:${topic.id}`;
|
|
const cached = storage.get(cacheKey);
|
|
if (cached) {
|
|
console.log(`[Learn] Cache hit voor topic: ${topic.id}`);
|
|
return cached;
|
|
}
|
|
|
|
const prompt = `Genereer een compleet leermodule voor het volgende onderwerp:
|
|
|
|
Label: ${topic.label}
|
|
Type: ${topic.type}
|
|
Beschrijving: ${topic.description}
|
|
|
|
Geef ALLEEN een JSON object terug met de volgende structuur:
|
|
{
|
|
"article": {
|
|
"title": "Artikel titel",
|
|
"intro": "Korte intro van 1-2 zinnen",
|
|
"sections": [
|
|
{ "heading": "Sectietitel", "body": "Sectietekst van minimaal 3 zinnen." }
|
|
],
|
|
"keyTakeaways": ["Lespunt 1", "Lespunt 2", "Lespunt 3"]
|
|
},
|
|
"slides": [
|
|
{ "title": "Diatitel", "bullets": ["Punt 1", "Punt 2", "Punt 3"], "speakerNote": "Toelichting voor de spreker." }
|
|
],
|
|
"podcastScript": "Een vloeiend gesproken script van ca. 300 woorden dat de inhoud samenvat als een podcast.",
|
|
"infographic": {
|
|
"headline": "Een korte, krachtige zin die het onderwerp samenvat (max 8 woorden)",
|
|
"tagline": "Een subkop van max 15 woorden",
|
|
"stats": [
|
|
{ "value": "Getal of %", "label": "Korte omschrijving", "icon": "📊" }
|
|
],
|
|
"steps": [
|
|
{ "number": 1, "title": "Staptitel", "description": "Korte beschrijving van 1 zin.", "icon": "🔑" }
|
|
],
|
|
"quote": "Een inspirerende of kernachtige quote over het onderwerp.",
|
|
"colorTheme": "teal"
|
|
}
|
|
}
|
|
|
|
Zorg voor minimaal 3 secties in het artikel, 4 slides, 3 statistieken en 3-5 stappen in de infographic.`;
|
|
|
|
|
|
const responseText = await anthropicApi.generateContent(CONTENT_GENERATION_SYSTEM, prompt);
|
|
|
|
let content;
|
|
try {
|
|
const jsonMatch = responseText.match(/\{[\s\S]*\}/);
|
|
content = JSON.parse(jsonMatch ? jsonMatch[0] : responseText);
|
|
} catch (e) {
|
|
throw new Error('AI kon geen geldige leerinhoud genereren.');
|
|
}
|
|
|
|
// Cache the content
|
|
storage.set(cacheKey, content);
|
|
return content;
|
|
}
|