This code imports various functions and modules, including selectModel
, askLlamaForAChapterSynopsis
, and Remarkable
, in order to generate content. It also defines a constant APOTHEOSIS
with narrative descriptions and uses an importer
to load various functions and modules from other files.
npm run import -- "write creatively llm"
const selectModel = importer.import("select llm")
const askLlamaForAChapterSynopsis = importer.import("ask llm to write chapter titles and descriptions")
const {Remarkable} = require('remarkable');
const md = new Remarkable({html: true, xhtmlOut: true, breaks: true});
const {safeurl} = importer.import("domain cache tools")
const APOTHEOSIS = {
'The Reluctant Hero Ascends to Godhood':
'Story: A reluctant protagonist begins as an ordinary individual in a world of chaos and oppression. Through a series of trials, they unlock a hidden power, gain wisdom, and eventually transcend human limitations. In their final act, they sacrifice their physical form to protect the world, merging with a cosmic force to become a guiding light for others.',
'The Savior Who Becomes the Idea':
'Story: A visionary leader emerges during a time of societal unrest, inspiring hope and uniting factions. After a climactic confrontation with their greatest enemy, they die but leave behind a legacy so powerful that their followers elevate them to a mythic status. Over time, their teachings and symbols are immortalized, and they are revered as more than human.',
'The Chosen One’s Transformation':
'Story: A young person with humble beginnings is revealed to be the "chosen one" destined to fulfill an ancient prophecy. Through years of hardship and growth, they confront their deepest fears, discover their ultimate purpose, and, in a climactic battle, ascend to a divine or superhuman state. They are no longer bound by mortal concerns but become a protector or overseer of the world.',
'The Seeker Achieves Cosmic Unity':
'Story: A curious soul sets out to uncover the mysteries of existence, delving into forbidden knowledge and seeking ultimate truth. After a lifetime of exploration and self-reflection, they achieve enlightenment, becoming one with the cosmos. Their physical form dissolves, but their essence merges with the fabric of reality, guiding others in subtle ways.',
'The Tragic Apotheosis':
'Story: A character seeking power for noble reasons gradually ascends beyond mortal limits, gaining immense abilities. However, the power isolates them, and they lose their humanity in the process. They ascend to godhood, but it is a lonely and burdensome existence, as they are unable to connect with the people they once sought to save.',
'The Redeemer Becomes Eternal':
'Story: A flawed individual begins as an outcast but eventually redeems themselves through acts of heroism and love. In their final moments, they perform an act of ultimate sacrifice that not only saves their companions but also purifies their soul. Their spirit lingers, providing guidance and hope to future generations as a benevolent force.',
'The Warrior Ascends Through Battle':
'Story: A great warrior, renowned for their prowess in battle, fights a final, epic confrontation against an overwhelming enemy. Though they fall in combat, their spirit rises, becoming a protector or deity for their people. Their legend is immortalized in song and ritual, ensuring their influence lasts for ages.',
}
// TODO: sort through responses based on heros journey on a specific topic
// https://en.wikipedia.org/wiki/Hero%27s_journey
async function askLlamaToWriteStory(topic, name, promptModel = 'Meta') {
if(typeof promptModel != 'function') {
promptModel = await selectModel(promptModel)
}
if(!topic) {
topic = 'a duck swimming in a pond for the first time'
}
let bookName = name
if(!name) {
let q0 = 'Brainstorm 12 funny but creative names for a book involving:\n' + topic
+ '\nRespond with only the list of fun names and nothing else.'
console.log("User: " + q0);
const a0 = await promptModel(q0);
console.log("AI: " + a0);
let names = a0.trim().split(/(^|\s*\n)[0-9]+\.\s*/).filter(a => a && a.trim().length > 0)
bookName = names[Math.round(Math.random() * (names.length-1))]
}
let chapters = await askLlamaForAChapterSynopsis('a book named ' + bookName + '\n' + topic)
let characters = await askLlamaForAChapterSynopsis(topic + '\n'
+ Object.keys(chapters).map(k => k + ' - ' + chapters[k]).join('\n')
+ '\nInclude character names followed by personalities, physical attributes, and likely scenarios they might appear.', 'character')
let interactions = await askLlamaForAChapterSynopsis('A sequal to ' + topic
+ '\nUsing this list of characters write chapters that include interactions between them:'
+ Object.keys(characters).map(k => k + ' - ' + characters[k]).join('\n')
+ '\nMake this half unique from existing chapters:\n'
+ Object.keys(chapters).join('\n'))
let bookChapters = []
let keys = Object.keys(chapters)
let prevChapter = ''
debugger
for(let i = 0; i < keys.length; i++) {
let q1 = 'Write a short story, include an entire Hero\'s journey, including departure, initiation, apotheosis, refusal of destiny, and successful return involving these characters (don\'t actually use the word apotheosis):\n'
+ Object.keys(characters).join('\n')
+ '\n' + APOTHEOSIS[Object.keys(APOTHEOSIS)[Math.round(Math.random() * (Object.keys(APOTHEOSIS).length - 1))]]
+ prevChapter
+ '\nChapter ' + (i + 1) + ' - ' + keys[i] + ' centers around this theme:\n' + chapters[keys[i]]
+ '\nDon\'t include any headings, just make it flow like a book chapter and nothing else.'
console.log("User: " + q1);
const a1 = await promptModel(q1);
console.log("AI: " + a1);
bookChapters[i] = '## Chapter ' + (i + 1) + ' - ' + keys[i] + '\n' + a1
let q5 = 'Summarize this chapter in two or three sentences:\n' + a1
console.log("User: " + q5);
const a5 = await promptModel(q5);
console.log("AI: " + a5);
prevChapter = '\nPreviously:' + a5
}
let bookInteractions = []
let keys2 = Object.keys(interactions)
for(let i = 0; i < keys2.length; i++) {
let q2 = 'Write a short story, include an entire Hero\'s journey, including departure, initiation, apotheosis, refusal of destiny, and successful return involving these characters (don\'t actually use the word apotheosis):\n'
+ Object.keys(characters).join('\n')
+ '\n' + APOTHEOSIS[Object.keys(APOTHEOSIS)[Math.round(Math.random() * (Object.keys(APOTHEOSIS).length - 1))]]
+ prevChapter
+ '\nChapter ' + (i + 1 + keys.length) + ' - ' + keys2[i] + ' centers around this theme:\n' + interactions[keys2[i]]
+ '\nDon\'t include any headings, just make it flow like a book chapter and nothing else.'
console.log("User: " + q2);
const a2 = await promptModel(q2);
console.log("AI: " + a2);
bookInteractions[i] = '## Chapter ' + (i + 1 + keys.length) + ' - ' + keys2[i] + '\n' + a2
let q6 = 'Summarize this chapter in two or three sentences:\n' + a2
console.log("User: " + q6);
const a6 = await promptModel(q6);
console.log("AI: " + a6);
prevChapter = '\nPreviously:' + a6
}
// TODO: generate synopsis
let q3 = 'Generate a synopsis of everything that\'s happened in this book:\n' + Object.values(chapters).join('\n')
console.log("User: " + q3);
const a3 = await promptModel(q3);
console.log("AI: " + a3);
let q4 = 'Generate a synopsis of everything that\'s happened in this book:\n' + Object.values(interactions).join('\n')
console.log("User: " + q4);
const a4 = await promptModel(q4);
console.log("AI: " + a4);
// TODO: generate scenes for each chapter, summaries
const mdHtml = md.render(topic, '# ' + bookName
+ '\n## Synopsis\n' + a3 + '\n' + a4
+ '\n' + bookChapters.join('\n')
+ '\n' + bookInteractions.join('\n'))
const filename = path.join(PROJECT_PATH, safeurl(topic) + '.html')
fs.writeFileSync(filename, mdHtml)
return mdHtml
}
module.exports = {
askLlamaToWriteStory
}
const { safeurl } = require('./domain-cache-tools');
const { path, fs } = require('fs');
const { Remarkable } = require('remarkable');
const { selectModel, askLlamaForAChapterSynopsis } = require('./importer');
const APOTHEOSIS = {
'The Reluctant Hero Ascends to Godhood':
'Story: A reluctant protagonist begins as an ordinary individual in a world of chaos and oppression. Through a series of trials, they unlock a hidden power, gain wisdom, and eventually transcend human limitations. In their final act, they sacrifice their physical form to protect the world, merging with a cosmic force to become a guiding light for others.',
'The Savior Who Becomes the Idea':
'Story: A visionary leader emerges during a time of societal unrest, inspiring hope and uniting factions. After a climactic confrontation with their greatest enemy, they die but leave behind a legacy so powerful that their followers elevate them to a mythic status. Over time, their teachings and symbols are immortalized, and they are revered as more than human.',
'The Chosen One’s Transformation':
'Story: A young person with humble beginnings is revealed to be the "chosen one" destined to fulfill an ancient prophecy. Through years of hardship and growth, they confront their deepest fears, discover their ultimate purpose, and, in a climactic battle, ascend to a divine or superhuman state. They are no longer bound by mortal concerns but become a protector or overseer of the world.',
'The Seeker Achieves Cosmic Unity':
'Story: A curious soul sets out to uncover the mysteries of existence, delving into forbidden knowledge and seeking ultimate truth. After a lifetime of exploration and self-reflection, they achieve enlightenment, becoming one with the cosmos. Their physical form dissolves, but their essence merges with the fabric of reality, guiding others in subtle ways.',
'The Tragic Apotheosis':
'Story: A character seeking power for noble reasons gradually ascends beyond mortal limits, gaining immense abilities. However, the power isolates them, and they lose their humanity in the process. They ascend to godhood, but it is a lonely and burdensome existence, as they are unable to connect with the people they once sought to save.',
'The Redeemer Becomes Eternal':
'Story: A flawed individual begins as an outcast but eventually redeems themselves through acts of heroism and love. In their final moments, they perform an act of ultimate sacrifice that not only saves their companions but also purifies their soul. Their spirit lingers, providing guidance and hope to future generations as a benevolent force.',
'The Warrior Ascends Through Battle':
'Story: A great warrior, renowned for their prowess in battle, fights a final, epic confrontation against an overwhelming enemy. Though they fall in combat, their spirit rises, becoming a protector or deity for their people. Their legend is immortalized in song and ritual, ensuring their influence lasts for ages.',
};
async function generateChapterSummaries(chapters, topic, promptModel) {
const chapterSummaries = [];
for (const key in chapters) {
const q = `Write a short summary of chapter ${key} involving ${topic} and the themes:\n${chapters[key]}`;
const a = await promptModel(q);
chapterSummaries.push(a);
}
return chapterSummaries;
}
async function generateBookChapters(topic, promptModel) {
const chapters = await askLlamaForAChapterSynopsis(topic);
const characters = await askLlamaForAChapterSynopsis(topic);
const interactions = await askLlamaForAChapterSynopsis(topic, 'interaction');
const chapterSummaries = await generateChapterSummaries(chapters, topic, promptModel);
const interactionSummaries = await generateChapterSummaries(interactions, topic, promptModel);
const bookChapters = [];
const bookInteractions = [];
const keys = Object.keys(chapters);
const prevChapter = '';
for (let i = 0; i < keys.length; i++) {
const q = `Write a short story, including the entire Hero's journey, involving these characters:\n${Object.keys(characters).join('\n')}\n${chapterSummaries[i]}\nDon't include any headings, just make it flow like a book chapter and nothing else.`;
const a = await promptModel(q);
bookChapters.push(`## Chapter ${i + 1} - ${keys[i]}\n${a}`);
prevChapter = `\nPreviously: ${chapterSummaries[i]}`;
}
for (let i = 0; i < Object.keys(interactions).length; i++) {
const q = `Write a short story, including the entire Hero's journey, involving these characters:\n${Object.keys(characters).join('\n')}\n${interactionSummaries[i]}\nDon't include any headings, just make it flow like a book chapter and nothing else.`;
const a = await promptModel(q);
bookInteractions.push(`## Chapter ${i + keys.length + 1} - ${Object.keys(interactions)[i]}\n${a}`);
prevChapter = `\nPreviously: ${interactionSummaries[i]}`;
}
return { bookChapters, bookInteractions };
}
async function generateBookSynopsis(topic, promptModel) {
const chapters = await askLlamaForAChapterSynopsis(topic);
const synopsis = await askLlamaForAChapterSynopsis(`Generate a synopsis of the book involving:\n${topic}`);
return synopsis;
}
async function askLlamaToWriteStory(topic, name, promptModel = 'Meta') {
if (typeof promptModel!== 'function') {
promptModel = await selectModel(promptModel);
}
if (!topic) {
topic = 'a duck swimming in a pond for the first time';
}
let bookName = name;
if (!name) {
let q0 = `Brainstorm 12 funny but creative names for a book involving:\n${topic}\nRespond with only the list of fun names and nothing else.`;
const a0 = await promptModel(q0);
bookName = a0.trim().split(/(^|\s*\n)[0-9]+\.\s*/).filter((a) => a && a.trim().length > 0)[Math.round(Math.random() * (a0.trim().split(/(^|\s*\n)[0-9]+\.\s*/).filter((a) => a && a.trim().length > 0).length - 1))];
}
const { bookChapters, bookInteractions } = await generateBookChapters(topic, promptModel);
const synopsis = await generateBookSynopsis(topic, promptModel);
const mdHtml = new Remarkable({ html: true, xhtmlOut: true, breaks: true }).render(topic, `# ${bookName}\n## Synopsis\n${synopsis}\n\n${bookChapters.join('\n')}\n\n${bookInteractions.join('\n')}`);
const filename = path.join(process.cwd(), safeurl(topic) + '.html');
fs.writeFileSync(filename, mdHtml);
return mdHtml;
}
module.exports = { askLlamaToWriteStory };
Code Breakdown
const selectModel = importer.import('select llm')
: Imports a function selectModel
from a module named'select llm' using an importer
.const askLlamaForAChapterSynopsis = importer.import('ask llm to write chapter titles and descriptions')
: Imports another function askLlamaForAChapterSynopsis
from a module named 'ask llm to write chapter titles and descriptions' using an importer
.const {Remarkable} = require('remarkable');
: Imports the Remarkable
class from the remarkable
module.const md = new Remarkable({html: true, xhtmlOut: true, breaks: true});
: Creates a new instance of the Remarkable
class, passing an options object to configure its behavior.const {safeurl} = importer.import('domain cache tools')
: Imports a function safeurl
from a module named 'domain cache tools' using an importer
.const APOTHEOSIS = {...}
: Defines an object APOTHEOSIS
with several properties, each of which is a narrative description for a story.This code snippet appears to be part of a larger application or framework, possibly related to content generation or writing, given the presence of functions like askLlamaForAChapterSynopsis
and the APOTHEOSIS
object that contains narrative descriptions.