fix(journaling): optimize serper video search queries to prevent MDX hallucination
Some checks failed
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 1s
Monorepo Pipeline / 🧪 Test (push) Successful in 59s
Monorepo Pipeline / 🧹 Lint (push) Failing after 2m0s
Monorepo Pipeline / 🏗️ Build (push) Successful in 5m9s
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 17:35:38 +01:00
parent 3a1a88db89
commit f4507ef121
3 changed files with 85 additions and 30 deletions

View File

@@ -22,6 +22,7 @@ export interface OptimizationTask {
export interface OptimizeFileOptions {
contextDir: string;
availableComponents?: ComponentDefinition[];
shouldRename?: boolean;
}
export class AiBlogPostOrchestrator {
@@ -115,7 +116,7 @@ export class AiBlogPostOrchestrator {
let finalPath = absPath;
let finalSlug = path.basename(absPath, ".mdx");
if (newFmMatch && newFmMatch[1]) {
if (options.shouldRename && newFmMatch && newFmMatch[1]) {
const titleMatch = newFmMatch[1].match(/title:\s*["']([^"']+)["']/);
if (titleMatch && titleMatch[1]) {
const newTitle = titleMatch[1];
@@ -137,12 +138,14 @@ export class AiBlogPostOrchestrator {
// Delete old file if the title changed significantly
try {
await fs.unlink(absPath);
} catch (e) {
/* ignore */
} catch (_err) {
// ignore
}
finalPath = newAbsPath;
}
}
} else if (newFmMatch && newFmMatch[1]) {
console.log(` Rename skipped (permalink stability active). If you want to rename, use --rename.`);
}
// Idea 5: Automatic Thumbnails
@@ -154,10 +157,8 @@ export class AiBlogPostOrchestrator {
);
if (this.thumbnailGenerator && !hasExistingThumbnail) {
console.log("🎨 Phase 5: Generating visual thumbnail...");
console.log("🎨 Phase 5: Generating/Linking visual thumbnail...");
try {
const visualPrompt = await this.generateVisualPrompt(finalContent);
// We assume public dir is relative to where this runs, usually monorepo root or apps/web
const webPublicDir = path.resolve(process.cwd(), "apps/web/public");
const thumbnailRelPath = `/blog/${finalSlug}.png`;
const thumbnailAbsPath = path.join(
@@ -166,12 +167,26 @@ export class AiBlogPostOrchestrator {
`${finalSlug}.png`,
);
await this.thumbnailGenerator.generateImage(
visualPrompt,
thumbnailAbsPath,
);
// Check if the physical file already exists
let physicalFileExists = false;
try {
await fs.access(thumbnailAbsPath);
physicalFileExists = true;
} catch (_err) {
// File does not exist
}
// Update frontmatter with thumbnail (SEO: we also want it as a hero)
if (physicalFileExists) {
console.log(`⏭️ Thumbnail already exists on disk, skipping generation: ${thumbnailAbsPath}`);
} else {
const visualPrompt = await this.generateVisualPrompt(finalContent);
await this.thumbnailGenerator.generateImage(
visualPrompt,
thumbnailAbsPath,
);
}
// Update frontmatter with thumbnail
if (finalContent.includes("thumbnail:")) {
finalContent = finalContent.replace(
/thumbnail:\s*["'].*?["']/,
@@ -184,7 +199,7 @@ export class AiBlogPostOrchestrator {
);
}
} catch (e) {
console.warn("⚠️ Thumbnail generation failed, skipping:", e);
console.warn("⚠️ Thumbnail processing failed, skipping:", e);
}
}
@@ -421,14 +436,16 @@ ${task.instructions || "None"}
BLOG POST BEST PRACTICES (MANDATORY):
- DEVIL'S ADVOCATE: Füge zwingend eine kurze kritische Sektion ein (z.B. mit \`<ComparisonRow>\` oder \`<IconList>\`), in der du offen die Nachteile/Kosten/Haken deiner eigenen Lösung ansprichst ("Der Haken an der Sache..."). Das baut Vertrauen bei B2B Entscheidenden auf.
- FAQ GENERATOR: Am absoluten Ende des Artikels erstellst du zwingend eine Markdown-Liste mit den 3 wichtigsten Fragen (FAQ) und Antworten (jeweils 2 Sätze) für Google Rich Snippets. Nutze dazu das \`<FAQSection>\` Component oder normales Markdown.
- SUBTLE CTAs: Webe 1-2 subtile CTAs für High-End Website Entwicklung ein (Beispiel: \`<Button href="/contact" variant="outline" size="normal">Performance-Check anfragen</Button>\` oder \`<Button href="/contact">Digitale Architektur anfragen</Button>\`). Platziere diese zwingend organisch nach Abschnitten mit hohem Mehrwert.
- Zitat-Varianten: Wenn du Organisationen oder Studien zitierst, nutze \`<ArticleQuote isCompany={true} ... />\`. Für Personen lass \`isCompany\` weg.
- FAQ GENERATOR: Am absoluten Ende des Artikels erstellst du zwingend eine Markdown-Liste mit den 3 wichtigsten Fragen (FAQ) und Antworten (jeweils 2 Sätze) für Google Rich Snippets. Nutze dazu das FAQSection Component oder normales Markdown.
- SUBTLE CTAs: Webe 1-2 subtile CTAs für High-End Website Entwicklung ein. Nutze ZWINGEND die Komponente [LeadMagnet] für diese Zwecke anstelle von einfachen Buttons. [LeadMagnet] bietet mehr Kontext und Vertrauen. Beispiel: <LeadMagnet title="Performance-Check anfragen" description="Wir analysieren Ihre Core Web Vitals und decken Umsatzpotenziale auf." buttonText="Jetzt analysieren lassen" href="/contact" variant="performance" />. Die Texte im LeadMagnet müssen absolut überzeugend, hochprofessionell und B2B-fokussiert sein (KEIN Robotik-Marketing-Sprech).
- MEME DIVERSITY: Nutze abwechslungsreiche Templates für Memes (distracted, gb, fine, ds, gru, cmm, ahb, uno, disastergirl, pigeon, rollsafe, pikachu, slap, exit, mordor, panik-kalm-panik). Wiederhole NIEMALS das gleiche Template in verschiedenen Artikeln, wenn du kannst. Wähle basierend auf dem Kontext des Artikels das passendste und sarkastischste Template.
- Zitat-Varianten: Wenn du Organisationen oder Studien zitierst, nutze ArticleQuote (mit isCompany=true für Firmen). Für Personen lass isCompany weg.
- Füge zwingend ein prägnantes 'TL;DR' ganz am Anfang ein.
- Füge ein sauberes '<TableOfContents />' ein.
- Füge ein sauberes TableOfContents ein.
- Verwende unsere Komponenten stilvoll für Visualisierungen.
- Agiere als hochprofessioneller Digital Architect und entferne alte MDX-Metadaten im Body.
- Fazit: Schließe JEDEN Artikel ZWINGEND mit einem starken, klaren 'Fazit' ab.
- ORIGINAL LANGUAGE QUOTES: Übersetze NIEMALS Zitate (z.B. in ArticleQuote). Behalte das Original (z.B. Englisch), wenn du Studien von Deloitte, McKinsey oder Aussagen von CEOs zitierst. Das erhöht die Authentizität im B2B-Mittelstand.
STRICT MDX OUTPUT RULES:
1. ONLY use the exact components defined above.