llm-pdf
Version:
Command Line tool to automate LLM and image models to generate a pdf by converting the generated text into markdown format and save it as a pdf document.
125 lines (113 loc) • 4.5 kB
JavaScript
import * as p from "@clack/prompts";
import color from "picocolors";
import { promises as fs } from "fs";
import main from "./bookGenerator.js";
(async () => {
console.clear();
p.intro(color.bold(color.magenta(" 📚 Book Content Generator 📚 ")));
const metadata = await p.group({
author: () =>
p.text({
message: color.cyan("Author's Name"),
placeholder: "Khaled Hosseini",
validate: (value) => {
if (!value) return "Please enter an author name!";
}
}),
title: () =>
p.text({
message: color.cyan("Book Title"),
placeholder: "The Kite Runner",
validate: (value) => {
if (!value) return "Please enter a book title!";
}
}),
mentions: () =>
p.text({
message: color.cyan("Special Mentions"),
placeholder: "Dedicated to my wonderful readers.",
}),
model: () =>
p.select({
message: color.cyan("Select generation model"),
initialValue: 'deepseek',
options: [
{
value: 'deepseek-ai/DeepSeek-R1-Distill-Llama-70B-free',
label: color.yellow('Deepseek') + color.gray(' - Quality'),
hint: 'Recommended for final drafts'
},
{
value: 'meta-llama/Llama-3.3-70B-Instruct-Turbo-Free',
label: color.yellow('Llama') + color.gray(' - Speed'),
hint: 'Recommended for quick drafts'
}
]
})
});
if (p.isCancel(metadata)) {
p.cancel(color.yellow("Operation cancelled by user"));
process.exit(0);
}
try {
await fs.writeFile("./content.txt", "");
p.log.success(color.green("New Book project initialized successfully"));
} catch (err) {
p.log.error(color.red("Error initializing file:"), err);
process.exit(1);
}
const inputs = [];
let counter = 0;
while (true) {
const input = await p.text({
message: color.cyan(`Content Entry #${counter + 1}`),
placeholder: "Enter your topic here...\n(Type -img at the end for image and /start to start generation)",
validate: (value) => {
if (value.length > 500) return "Entry too long! (max 500 characters)";
}
});
if (p.isCancel(input)) {
p.cancel(color.yellow("Operation cancelled by user"));
process.exit(0);
}
if (input === "/start") {
if (inputs.length === 0) {
p.log.warning(color.yellow("No content entries!"));
const cont = await p.confirm({
message: "Start generation with empty content?",
});
if (p.isCancel(cont)) process.exit(0);
if (!cont) continue;
}
break;
}
try {
await fs.appendFile("./content.txt", input + "\n");
inputs.push(input);
counter++;
p.log.success(color.green(`Entry #${counter} saved successfully`));
} catch (err) {
p.log.error(color.red("Error saving entry:"), err);
}
}
p.note(
[
`${color.bold('Author:')} ${metadata.author}`,
`${color.bold('Title:')} ${metadata.title}`,
`${color.bold('Mentions:')} ${metadata.mentions}`,
`${color.bold('Model:')} ${metadata.model === 'deepseek' ? 'Deepseek 🐢' : 'Llama 🚀'}`,
`\n${color.bold('CONTENT:')}\n${inputs.join("\n")}`
].join("\n\n"),
color.bgMagenta(color.white(" Book Summary "))
);
try {
await main(metadata.author, metadata.title, metadata.mentions, metadata.model);
p.log.success(color.green("Book generated successfully! 🎉"));
p.outro(color.bold(color.green("Happy reading!")));
} catch (err) {
p.log.error(color.red("Generation failed! ❌"));
p.log.error(color.red("Error details:"), err);
process.exit(1);
}
})();