fix summary

Closes #1

Signed-off-by: Xe Iaso <me@xeiaso.net>
This commit is contained in:
Xe Iaso 2023-04-23 10:04:27 -04:00
parent 50410c7910
commit de0737f641

View File

@ -1,5 +1,5 @@
import * as fs from "node:fs/promises"; import * as fs from "node:fs/promises";
import { OpenAIApi } from "openai"; import { ChatCompletionRequestMessage, OpenAIApi } from "openai";
import PlotGenerator, { Plot } from "@ebooks/plottoriffic"; import PlotGenerator, { Plot } from "@ebooks/plottoriffic";
export const authorBio = `Yasomi Midori is a science fiction author who explores the themes of identity, memory, and technology in her novels. Her debut novel “The Memory Thief” was a critically acclaimed bestseller that captivated readers with its thrilling plot and complex characters. Yasomi also contributes to the Xe Iaso blog as the character Mimi, a hacker and activist who exposes the secrets of the powerful corporations that control the world. Yasomi was born and raised in Tokyo, Japan, where she developed a passion for reading and writing at an early age. She studied computer science and literature at the University of Tokyo, and worked as a software engineer before becoming a full-time writer. She lives in Kyoto with her husband and two cats.`; export const authorBio = `Yasomi Midori is a science fiction author who explores the themes of identity, memory, and technology in her novels. Her debut novel “The Memory Thief” was a critically acclaimed bestseller that captivated readers with its thrilling plot and complex characters. Yasomi also contributes to the Xe Iaso blog as the character Mimi, a hacker and activist who exposes the secrets of the powerful corporations that control the world. Yasomi was born and raised in Tokyo, Japan, where she developed a passion for reading and writing at an early age. She studied computer science and literature at the University of Tokyo, and worked as a software engineer before becoming a full-time writer. She lives in Kyoto with her husband and two cats.`;
@ -42,24 +42,38 @@ export const createAndParseSummary = async (
plot: Plot plot: Plot
): Promise<Summary> => { ): Promise<Summary> => {
console.log("generating plot summary"); console.log("generating plot summary");
const promptBase = `Write me the following about the following plot summary for a novel:
- A two to five word title for the novel starting with "Title: " and followed by two newlines. For example: "Fresh Beginnings" or "Jared's Adventure through Crime". const promptBase = [
- A detailed plot summary for the story starting with "Plot Summary: " and followed by two newlines. The plot summary should be on the same line as the prefix. Adapt the story to be about peer to peer networks somehow. "You are a Novel generation AI, write plot summaries for novels given a specified format.",
- The string "Chapter Summaries" followed by two newlines. '- A two to five word novel title in the format of "Title: " followed by two newlines. (Examples: "Fresh Beginnings", "Jared\'s Adventure")',
- A markdown list of detailed chapter summaries in at least 3 sentences and titles for each of the 15 chapters that a novel based on the plot summary would have. Surround each chapter title in quotes and put a dash after the name like this: '- A detailed plot summary in the format of "Plot Summary: " followed by two newlines. The story MUST relate to peer to peer networks.',
'- A section titled "Chapter Summaries:" followed by two newlines which will follow a specified structure.',
"\t- A markdown style list of very detailed summaries of each chapter. Each must be 3 sentences and have a title for each chapter. There MUST be 15 chapters. Each chapter must tie in to the overaching plot summary. They should follow a specified format.",
'\t\t- Each chapter section should be in the format of "Chapter Name: Chapter summary." followed with a single newline. DO NOT include the word "Chapter" or the chapter number. You MUST put them on the same line. DO NOT put them on separate lines.',
];
- Chapter name - Chapter summary goes here. More words in the summary go here. /* Create the messages array */
- Second chapter name - Second chapter summary goes here.`; var messages: Array<ChatCompletionRequestMessage> = new Array<ChatCompletionRequestMessage>();
const promptObject: ChatCompletionRequestMessage = {
role: "user",
content: `${plot.plot}`,
};
/* Push the messages into the array */
promptBase.map((message) => {
const systemObject: ChatCompletionRequestMessage = {
role: "system",
content: `${message}`,
};
messages.push(systemObject);
});
messages.push(promptObject);
const summary = await openai.createChatCompletion({ const summary = await openai.createChatCompletion({
model: "gpt-3.5-turbo", model: "gpt-3.5-turbo",
messages: [ messages,
{
role: "user",
content: promptBase + "\n\n" + plot.plot,
},
],
}); });
if (!!summary.data.usage) { if (!!summary.data.usage) {
@ -70,12 +84,13 @@ export const createAndParseSummary = async (
} }
const summaryText = summary.data.choices[0].message?.content; const summaryText = summary.data.choices[0].message?.content;
console.log(summaryText);
await fs.writeFile(`${dirName}/summary.txt`, summaryText as string); await fs.writeFile(`${dirName}/summary.txt`, summaryText as string);
const titleRegex = /^Title: (.+)$/gm; const titleRegex = /^Title: (.+)$/gm;
const plotSummaryRegex = /^Plot Summary: (.+)$/gm; const plotSummaryRegex = /^Plot Summary: (.+)$/gm;
const chapterSummaryRegex = /^- (.+) ?- (.+)$/gm; const chapterSummaryRegex = /^- (.+): (.+)$/gm;
let title = summaryText?.split("\n", 2)[0].split(titleRegex)[1] as string; let title = summaryText?.split("\n", 2)[0].split(titleRegex)[1] as string;
@ -135,7 +150,7 @@ export const createChapterScenes = async (
console.log(`creating chapter scene information for chapter ${ch.title}`); console.log(`creating chapter scene information for chapter ${ch.title}`);
const prompt = const prompt =
`Given the following plot summary, character information, and chapter information, write descriptions of scenes that would happen in that chapter. End each description with two newlines. Write at least 6 scenes. DO NOT only write one scene. Use detail and be creative. DO NOT include the chapter title in your output. ONLY output the scenes separated by newlines like this. `Given the following plot summary, character information, and chapter information, write descriptions of scenes that would happen in that chapter. End each description with two newlines. Write at least six to eight scenes. DO NOT only write one scene. Use detail and be creative. DO NOT include the chapter title in your output. ONLY output the scenes separated by newlines like this.
What happens first. What happens first.
@ -188,7 +203,7 @@ export const writeChapterScene = async (
scene: string scene: string
): Promise<string> => { ): Promise<string> => {
const prompt = const prompt =
`Given the following information, write the scene of the novel. Be detailed about the setting and character descriptions. End each paragraph with two newlines. Write many sentences. ONLY return the text of the novel. `Given the following information, write the scene of the novel. Be detailed about the setting and character descriptions. End each paragraph with two newlines. Write many sentences. Write like Steven King or Margaret Mitchell. ONLY return the text of the novel.
` + ` +
summary.characters.map((char) => `- ${char.name}: ${char.role}`).join("\n") + summary.characters.map((char) => `- ${char.name}: ${char.role}`).join("\n") +
` `