feat(content-engine): add autonomous validation layer to actively detect and correct hallucinated meme templates without user intervention
All checks were successful
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 1s
Monorepo Pipeline / 🧪 Test (push) Successful in 1m0s
Monorepo Pipeline / 🧹 Lint (push) Successful in 2m46s
Monorepo Pipeline / 🏗️ Build (push) Successful in 4m49s
Monorepo Pipeline / 🚀 Release (push) Has been skipped
Monorepo Pipeline / 🐳 Build Directus (Base) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Gatekeeper (Product) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Build-Base (push) Has been skipped
Monorepo Pipeline / 🐳 Build Production Runtime (push) Has been skipped

This commit is contained in:
2026-02-22 18:23:44 +01:00
parent 90a9e34c7e
commit d5632b009a

View File

@@ -405,24 +405,26 @@ Return ONLY the JSON.`,
.join("\n\n");
const memeTemplates = [
"distracted",
"gb",
"fine",
"ds",
"gru",
"cmm",
"ahb",
"uno",
"db", // Distracted Boyfriend
"gb", // Galaxy Brain
"fine", // This is Fine
"ds", // Daily Struggle
"gru", // Gru's Plan
"cmm", // Change My Mind
"astronaut", // Always Has Been (ahb)
"disastergirl",
"pigeon",
"pigeon", // Is this a pigeon?
"rollsafe",
"pikachu",
"slap",
"exit",
"slap", // Will Smith
"exit", // Left Exit 12
"mordor",
"panik-kalm-panik",
"womanyellingcat",
"woman-cat", // Woman yelling at cat
"grumpycat",
"sadfrog",
"stonks",
"same", // They're the same picture
"spongebob",
];
const forcedMeme =
memeTemplates[Math.floor(Math.random() * memeTemplates.length)];
@@ -499,37 +501,53 @@ CRITICAL GUIDELINES (NEVER BREAK THESE):
let rawContent = response.choices[0].message.content || task.content;
rawContent = this.cleanResponse(rawContent, socialPosts);
// Validation Layer: Check Mermaid syntax
if (retryCount < 2 && rawContent.includes("<Mermaid>")) {
// --- Autonomous Validation Layer ---
let hasError = false;
let errorFeedback = "";
// 1. Validate Meme Templates
const memeRegex = /<ArticleMeme[^>]+template=["']([^"']+)["'][^>]*>/g;
let memeMatch;
const invalidMemes: string[] = [];
while ((memeMatch = memeRegex.exec(rawContent)) !== null) {
if (!memeTemplates.includes(memeMatch[1])) {
invalidMemes.push(memeMatch[1]);
}
}
if (invalidMemes.length > 0) {
hasError = true;
errorFeedback += `\n- You hallucinated invalid meme templates: ${invalidMemes.join(", ")}. You MUST ONLY use templates from this exact list: ${memeTemplates.join(", ")}. DO NOT INVENT TEMPLATES.\n`;
}
// 2. Validate Mermaid Syntax
if (rawContent.includes("<Mermaid>")) {
console.log("🔍 Validating Mermaid syntax in AI response...");
const mermaidBlocks = this.extractMermaidBlocks(rawContent);
let hasError = false;
let errorFeedback = "";
for (const block of mermaidBlocks) {
const validationResult = await this.validateMermaidSyntax(block);
if (!validationResult.valid) {
hasError = true;
errorFeedback += `\nInvalid Mermaid block:\n${block}\nError context: ${validationResult.error}\n\n`;
errorFeedback += `\n- Invalid Mermaid block:\n${block}\nError context: ${validationResult.error}\n`;
}
}
}
if (hasError) {
console.log(
`Invalid Mermaid syntax detected. Retrying compilation (Attempt ${retryCount + 1}/2)...`,
);
return this.compileArticle(
{
...task,
content: `The previous attempt failed because you generated invalid Mermaid.js syntax. Please rewrite the MDX and FIX the following Mermaid errors. \n\nErrors:\n${errorFeedback}\n\nOriginal Draft:\n${task.content}`,
},
facts,
competitorInsights,
socialPosts,
internalLinks,
retryCount + 1,
);
}
if (hasError && retryCount < 3) {
console.log(
`Validation errors detected. Retrying compilation (Attempt ${retryCount + 1}/3)...`,
);
return this.compileArticle(
{
...task,
content: `CRITICAL ERROR IN PREVIOUS ATTEMPT:\nYour generated MDX contained the following errors that MUST be fixed:\n${errorFeedback}\n\nPlease rewrite the MDX and FIX these errors. Pay strict attention to the rules.\n\nOriginal Draft:\n${task.content}`,
},
facts,
competitorInsights,
socialPosts,
internalLinks,
retryCount + 1,
);
}
return rawContent;