Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 10s
Build & Deploy / 🧪 QA (push) Failing after 2m24s
Build & Deploy / 🏗️ Build (push) Failing after 3m40s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 3s
89 lines
2.5 KiB
TypeScript
89 lines
2.5 KiB
TypeScript
"use server";
|
|
|
|
import { config } from "../../../content-engine.config";
|
|
import { revalidatePath } from "next/cache";
|
|
import { parseMarkdownToLexical } from "../utils/lexicalParser";
|
|
import { getPayloadHMR } from "@payloadcms/next/utilities";
|
|
import configPromise from "@payload-config";
|
|
|
|
export async function optimizePostText(
|
|
draftContent: string,
|
|
instructions?: string,
|
|
) {
|
|
try {
|
|
const payload = await getPayloadHMR({ config: configPromise });
|
|
const globalAiSettings = await payload.findGlobal({ slug: "ai-settings" });
|
|
const customSources =
|
|
globalAiSettings?.customSources?.map((s: any) => s.sourceName) || [];
|
|
|
|
const OPENROUTER_KEY =
|
|
process.env.OPENROUTER_KEY || process.env.OPENROUTER_API_KEY;
|
|
const REPLICATE_KEY = process.env.REPLICATE_API_KEY;
|
|
|
|
if (!OPENROUTER_KEY) {
|
|
throw new Error(
|
|
"OPENROUTER_KEY or OPENROUTER_API_KEY not found in environment.",
|
|
);
|
|
}
|
|
|
|
const importDynamic = new Function(
|
|
"modulePath",
|
|
"return import(modulePath)",
|
|
);
|
|
const { AiBlogPostOrchestrator } = await importDynamic(
|
|
"@mintel/content-engine",
|
|
);
|
|
|
|
const orchestrator = new AiBlogPostOrchestrator({
|
|
apiKey: OPENROUTER_KEY,
|
|
replicateApiKey: REPLICATE_KEY,
|
|
model: "google/gemini-3-flash-preview",
|
|
});
|
|
|
|
// Fetch context documents purely from DB
|
|
const contextDocsData = await payload.find({
|
|
collection: "context-files",
|
|
limit: 100,
|
|
});
|
|
const projectContext = contextDocsData.docs.map((doc) => doc.content);
|
|
|
|
const optimizedMarkdown = await orchestrator.optimizeDocument({
|
|
content: draftContent,
|
|
projectContext,
|
|
availableComponents: config.components,
|
|
instructions,
|
|
internalLinks: [],
|
|
customSources,
|
|
});
|
|
|
|
// The orchestrator currently returns Markdown + JSX tags.
|
|
// We convert this mixed string into a basic Lexical AST map.
|
|
|
|
if (!optimizedMarkdown || typeof optimizedMarkdown !== "string") {
|
|
throw new Error("AI returned invalid markup.");
|
|
}
|
|
|
|
const blocks = parseMarkdownToLexical(optimizedMarkdown);
|
|
|
|
return {
|
|
success: true,
|
|
lexicalAST: {
|
|
root: {
|
|
type: "root",
|
|
format: "",
|
|
indent: 0,
|
|
version: 1,
|
|
children: blocks,
|
|
direction: "ltr",
|
|
},
|
|
},
|
|
};
|
|
} catch (error: any) {
|
|
console.error("Failed to optimize post:", error);
|
|
return {
|
|
success: false,
|
|
error: error.message || "An unknown error occurred during optimization.",
|
|
};
|
|
}
|
|
}
|