Files
anything-llm/server/utils/agents/aibitat/plugins/create-files/pptx/test-themes.js
Timothy Carambat 7aaea7f514 File creation agent skills (#5280)
* Powerpoint File Creation (#5278)

* wip

* download card

* UI for downloading

* move to fs system with endpoint to pull files

* refactor UI

* final-pass

* remove save-file-browser skill and refactor

* remove fileDownload event

* reset

* reset file

* reset timeout

* persist toggle

* Txt creation (#5279)

* wip

* download card

* UI for downloading

* move to fs system with endpoint to pull files

* refactor UI

* final-pass

* remove save-file-browser skill and refactor

* remove fileDownload event

* reset

* reset file

* reset timeout

* wip

* persist toggle

* add arbitrary text creation file

* Add PDF document generation with markdown formatting (#5283)

add support for branding in bottom right corner
refactor core utils and frontend rendering

* Xlsx document creation (#5284)

add Excel doc & sheet creation

* Basic docx creation (#5285)

* Basic docx creation

* add test theme support + styling and title pages

* simplify skill selection

* handle TG attachments

* send documents over tg

* lazy import

* pin deps

* fix lock

* i18n for file creation (#5286)

i18n for file-creation
connect #5280

* theme overhaul

* Add PPTX subagent for better results

* forgot files

* Add PPTX subagent for better results (#5287)

* Add PPTX subagent for better results

* forgot files

* make sub-agent use proper tool calling if it can and better UI hints
2026-03-30 15:13:39 -07:00

144 lines
3.9 KiB
JavaScript

/**
* Generate a preview presentation for every theme using the same rendering
* pipeline as the production tool. Run from repo root:
*
* node server/utils/agents/aibitat/plugins/create-files/pptx/test-themes.js
*
* Output → storage/generated-files/theme-previews/
*/
const path = require("path");
const fs = require("fs");
const PptxGenJS = require("pptxgenjs");
const createFilesLib = require("../lib.js");
const { getTheme, getAvailableThemes } = require("./themes.js");
const {
renderTitleSlide,
renderSectionSlide,
renderContentSlide,
renderBlankSlide,
} = require("./utils.js");
const SAMPLE_SLIDES = [
{
title: "Executive Summary",
content: [
"Revenue grew 23% year-over-year to $4.2B",
"Operating margin expanded 180bps to 28.4%",
"Customer retention rate improved to 94.7%",
"Three strategic acquisitions completed in Q3",
],
notes: "Emphasize the margin expansion story",
},
{
layout: "section",
title: "Strategic Priorities",
subtitle: "Key initiatives for the next fiscal year",
},
{
title: "Market Opportunity",
subtitle: "Total addressable market analysis",
content: [
"Global TAM estimated at $180B by 2027",
"Our serviceable market represents $42B opportunity",
"Current market share: 8.3% with clear path to 15%",
"Three adjacent markets identified for expansion",
"Competitive moat strengthening through R&D investment",
],
},
{
title: "Financial Performance",
table: {
headers: ["Metric", "FY2024", "FY2025", "Growth"],
rows: [
["Revenue", "$3.4B", "$4.2B", "+23%"],
["Gross Margin", "62.1%", "64.8%", "+270bps"],
["Operating Income", "$910M", "$1.19B", "+31%"],
["Free Cash Flow", "$780M", "$1.02B", "+31%"],
],
},
},
{
title: "Next Steps & Timeline",
content: [
"Q1: Launch Phase 2 of platform modernization",
"Q2: Complete integration of acquired entities",
"Q3: Enter two new geographic markets",
"Q4: Achieve $5B annual revenue run-rate",
],
},
];
async function generateThemePreview(themeName, outputDir) {
const theme = getTheme(themeName);
const pptx = new PptxGenJS();
pptx.title = `${theme.name} Theme Preview`;
pptx.author = "AnythingLLM";
pptx.company = "AnythingLLM";
const totalSlides = SAMPLE_SLIDES.length;
const titleSlide = pptx.addSlide();
renderTitleSlide(
titleSlide,
pptx,
{ title: `${theme.name} Theme`, author: "AnythingLLM Theme Preview" },
theme
);
SAMPLE_SLIDES.forEach((slideData, index) => {
const slide = pptx.addSlide();
const slideNumber = index + 1;
const layout = slideData.layout || "content";
switch (layout) {
case "title":
case "section":
renderSectionSlide(
slide,
pptx,
slideData,
theme,
slideNumber,
totalSlides
);
break;
case "blank":
renderBlankSlide(slide, pptx, theme, slideNumber, totalSlides);
break;
default:
renderContentSlide(
slide,
pptx,
slideData,
theme,
slideNumber,
totalSlides
);
break;
}
});
const filename = `theme-preview-${themeName}.pptx`;
const filepath = path.join(outputDir, filename);
await pptx.writeFile({ fileName: filepath });
console.log(`${theme.name}${filename}`);
}
async function main() {
const baseDir = await createFilesLib.getOutputDirectory();
const outputDir = path.join(baseDir, "theme-previews");
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
console.log("Generating theme previews…\n");
const themes = getAvailableThemes();
for (const themeName of themes) {
await generateThemePreview(themeName, outputDir);
}
console.log(`\nDone! ${themes.length} previews saved to:\n ${outputDir}`);
}
main().catch(console.error);