Some checks failed
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 2s
Monorepo Pipeline / 🧪 Test (push) Successful in 1m6s
Monorepo Pipeline / 🏗️ Build (push) Successful in 2m52s
Monorepo Pipeline / 🧹 Lint (push) Successful in 3m1s
Monorepo Pipeline / 🚀 Release (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
🏥 Server Maintenance / 🧹 Prune & Clean (push) Failing after 4s
109 lines
2.9 KiB
TypeScript
109 lines
2.9 KiB
TypeScript
import { PayloadRequest } from "payload";
|
|
import { parseMarkdownToLexical } from "../utils/lexicalParser.js";
|
|
|
|
export const optimizePostEndpoint = async (req: PayloadRequest) => {
|
|
try {
|
|
let body: any = {};
|
|
try {
|
|
if (req.body) {
|
|
// req.json() acts as a method in Next.js/Payload req wrapper
|
|
body = (await req.json?.()) || {};
|
|
}
|
|
} catch (e) {
|
|
// Ignore JSON parse error, body remains empty
|
|
}
|
|
|
|
const { draftContent, instructions } = body as {
|
|
draftContent?: string;
|
|
instructions?: string;
|
|
};
|
|
|
|
if (!draftContent) {
|
|
return Response.json(
|
|
{ success: false, error: "Missing draftContent" },
|
|
{ status: 400 },
|
|
);
|
|
}
|
|
|
|
const globalAiSettings = (await req.payload.findGlobal({
|
|
slug: "ai-settings",
|
|
})) as any;
|
|
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) {
|
|
return Response.json(
|
|
{ error: "OPENROUTER_KEY not found in environment." },
|
|
{ status: 500 },
|
|
);
|
|
}
|
|
|
|
// Dynamically import to avoid bundling it into client components that might accidentally import this file
|
|
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",
|
|
});
|
|
|
|
const contextDocsData = await req.payload.find({
|
|
collection: "context-files" as any,
|
|
limit: 100,
|
|
});
|
|
const projectContext = contextDocsData.docs.map((doc: any) => doc.content);
|
|
|
|
const optimizedMarkdown = await orchestrator.optimizeDocument({
|
|
content: draftContent,
|
|
projectContext,
|
|
availableComponents: [],
|
|
instructions,
|
|
internalLinks: [],
|
|
customSources,
|
|
});
|
|
|
|
if (!optimizedMarkdown || typeof optimizedMarkdown !== "string") {
|
|
return Response.json(
|
|
{ error: "AI returned invalid markup." },
|
|
{ status: 500 },
|
|
);
|
|
}
|
|
|
|
const blocks = parseMarkdownToLexical(optimizedMarkdown);
|
|
|
|
return Response.json({
|
|
success: true,
|
|
lexicalAST: {
|
|
root: {
|
|
type: "root",
|
|
format: "",
|
|
indent: 0,
|
|
version: 1,
|
|
children: blocks,
|
|
direction: "ltr",
|
|
},
|
|
},
|
|
});
|
|
} catch (error: any) {
|
|
console.error("Failed to optimize post in endpoint:", error);
|
|
return Response.json(
|
|
{
|
|
success: false,
|
|
error:
|
|
error.message || "An unknown error occurred during optimization.",
|
|
},
|
|
{ status: 500 },
|
|
);
|
|
}
|
|
};
|