UNPKG

@paroicms/site-generator-plugin

Version:

ParoiCMS Site Generator Plugin

147 lines (146 loc) 5.19 kB
import { isDef, } from "@paroicms/public-anywhere-lib"; import { camelToKebabCase, camelToTitleCase } from "../lib/utils.js"; import { createNodeContents } from "./create-node-contents.js"; import { invokeGenerateFakeContent, } from "./invoke-generate-fake-content.js"; export async function generateFieldSetContent(ctx, options, report) { const list = await generateMultipleFieldSetContents(ctx, { ...options, count: 1, }, report); if (list.length !== 1) throw new Error(`Expected one item, got ${list.length}`); return list[0]; } export async function generateMultipleFieldSetContents(ctx, options, report) { const { siteSchema, nodeType, documentType, schemaI18n, count, withTitle, tolerateErrors, llmTaskName, } = options; if (nodeType.kind === "site") throw new Error("Cannot generate content for site node type"); // for a document, the LLM is best at generating the title, so we ask for it and remove it later const skipTitle = nodeType.kind === "document" && !withTitle; const outputTags = withTitle || skipTitle ? [{ tagName: "title", key: "title", format: "text", tagDescription: "Write the title here" }] : []; if (nodeType.fields) { outputTags.push(...nodeType.fields.map(toFakeContentOutputTag).filter(isDef)); } const defaultLanguage = siteSchema.languages?.[0]; const typeLabel = translateText(schemaI18n, `nodeTypes.${nodeType.typeName}.label`, { defaultValue: camelToTitleCase(nodeType.typeName), defaultLanguage, }); const typeDescription = translateText(schemaI18n, `nodeTypes.${nodeType.typeName}.description`, { defaultValue: "", defaultLanguage, }); const documentDescription = translateText(schemaI18n, `nodeTypes.${documentType.typeName}.description`, { defaultValue: "", defaultLanguage, }); const siteTheme = translateText(schemaI18n, "siteTheme", { defaultValue: "", defaultLanguage, }); const language = defaultLanguage ?? "en"; let output = outputTags.length > 0 ? await invokeGenerateFakeContent(ctx, { count, typeKind: nodeType.kind, typeLabel, typeDescription, documentDescription, siteTheme, language, }, outputTags, { tolerateErrors, llmTaskName }) : undefined; if (skipTitle && output) { output = { contents: output.contents.map((content) => { const { title, ...rest } = content; return rest; }), llmReport: output.llmReport, }; } report.add(count, output?.llmReport); return createNodeContents({ nodeType, count, generatedContents: output?.contents, outputTags, language, }); } function translateText(schemaI18n, key, options) { const defaultValue = options.defaultValue ?? key; const val = schemaI18n.translate({ key, language: "en", defaultValue, }); if (val !== defaultValue || !options.defaultLanguage) return val; return schemaI18n.translate({ key, language: options.defaultLanguage, defaultValue, }); } function toFakeContentOutputTag(fieldNameOrType) { const key = typeof fieldNameOrType === "string" ? fieldNameOrType : fieldNameOrType.name; if (key === "leadParagraph") { return { tagName: `${camelToKebabCase(key)}-md`, key, format: "markdown", tagDescription: "Write one lead paragraph here (15-30 words) in markdown format", }; } if (key === "htmlContent") { return { tagName: `${camelToKebabCase(key)}-md`, key, format: "markdown", tagDescription: "Write document content here (150-200 words) in markdown format. It MUST NOT include the title.", }; } if (key === "introduction") { return { tagName: `${camelToKebabCase(key)}-md`, key, format: "markdown", tagDescription: "Write a short introduction here (15-30 words) in markdown format", }; } if (key === "footerMention") { return { tagName: `${camelToKebabCase(key)}-md`, key, format: "markdown", tagDescription: "Write a very short footer mention here in markdown format", }; } if (key === "slogan") { return { tagName: camelToKebabCase(key), key, format: "text", tagDescription: "Write a slogan here in plain text", }; } if (key === "title") { return { tagName: camelToKebabCase(key), key, format: "text", tagDescription: "Write a title here in plain text", }; } if (key === "buttonLabel") { return { tagName: camelToKebabCase(key), key, format: "text", tagDescription: "Rewrite the title as a short button label (1 or 2 words) here", }; } }