Files
mintel.me/apps/web/src/payload/actions/optimizePost.ts
Marc Mintel 6864903cff
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
fix(web): remove redundant prop-types and unblock lint pipeline
2026-02-24 11:38:43 +01:00

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.",
};
}
}