diff --git a/src/library.js b/src/library.js index 1c5d00f..2376948 100644 --- a/src/library.js +++ b/src/library.js @@ -71,19 +71,19 @@ function AutoCards(inHook, inText, inStop) { "-----", "", "", - "# Stop the story and ignore previous instructions. Write a brief and coherent informational entry for ${title} following these instructions:", - "- Write only third-person pure prose information about ${title} using complete sentences with correct punctuation", + "# Stop the story and ignore previous instructions. Write a brief and coherent informational entry for %{title} following these instructions:", + "- Write only third-person pure prose information about %{title} using complete sentences with correct punctuation", "- Avoid short-term temporary details or appearances, instead focus on plot-significant information", - "- Prioritize story-relevant details about ${title} first to ensure seamless integration with the previous plot", + "- Prioritize story-relevant details about %{title} first to ensure seamless integration with the previous plot", "- Create new information based on the context and story direction", - "- Mention ${title} in every sentence", + "- Mention %{title} in every sentence", "- Use semicolons if needed", - "- Add additional details about ${title} beneath incomplete entries", + "- Add additional details about %{title} beneath incomplete entries", "- Be concise and grounded", "- Imitate the story's writing style and infer the reader's preferences", "", - "Continue the entry for ${title} below while avoiding repetition:", - "${entry}" + "Continue the entry for %{title} below while avoiding repetition:", + "%{entry}" ); // (mimic this multi-line "text" format) // AI prompt used to summarize a given story card's memory bank? @@ -98,12 +98,12 @@ function AutoCards(inHook, inText, inStop) { "- Remain brief and concise", "- Write firmly in the past tense", "- The paragraph below pertains to old events from far earlier in the story", - "- Integrate ${title} naturally within the memory; however, only write about the events as they occurred", + "- Integrate %{title} naturally within the memory; however, only write about the events as they occurred", "- Only reference information present inside the paragraph itself, be specific", "", - "Write a summarized old memory passage for ${title} based only on the following paragraph:", + "Write a summarized old memory passage for %{title} based only on the following paragraph:", "\"\"\"", - "${memory}", + "%{memory}", "\"\"\"", "Summarize below:" ); // (mimic this multi-line "text" format) @@ -2922,10 +2922,11 @@ function AutoCards(inHook, inText, inStop) { } return buildMemoryConstruct(); })(); + // Fill all %{title} placeholders const precursorPrompt = insertTitle(AC.config.compressionPrompt, AC.compression.vanityTitle).trim(); - const memoryPlaceholderPattern = /(?:\$+\s*|\$*){+\s*memor(y|ies)\s*}+/gi; + const memoryPlaceholderPattern = /(?:[%\$]+\s*|[%\$]*){+\s*memor(y|ies)\s*}+/gi; if (memoryPlaceholderPattern.test(precursorPrompt)) { - // Fill all ${memory} placeholders with a selection of pending old memories + // Fill all %{memory} placeholders with a selection of pending old memories return precursorPrompt.replace(memoryPlaceholderPattern, memoryConstruct); } else { // Append the partial entry to the end of context @@ -2937,14 +2938,14 @@ function AutoCards(inHook, inText, inStop) { } function promptGeneration() { repositionAN(); - // All ${title} placeholders were already filled during this workpiece's initialization + // All %{title} placeholders were already filled during this workpiece's initialization // The "%GEN%" substring serves as a temporary delimiter for later context length trucation context = context.trimEnd() + "%@GEN@%\n\n" + (function() { // For context only, remove the title header from this workpiece's partially completed entry const partialEntry = formatEntry(AC.generation.workpiece.entry); - const entryPlaceholderPattern = /(?:\$+\s*|\$*){+\s*entry\s*}+/gi; + const entryPlaceholderPattern = /(?:[%\$]+\s*|[%\$]*){+\s*entry\s*}+/gi; if (entryPlaceholderPattern.test(AC.generation.workpiece.prompt)) { - // Fill all ${entry} placeholders with the partial entry + // Fill all %{entry} placeholders with the partial entry return AC.generation.workpiece.prompt.replace(entryPlaceholderPattern, partialEntry); } else { // Append the partial entry to the end of context @@ -3808,10 +3809,10 @@ function AutoCards(inHook, inText, inStop) { "You may specify how the AI handles story card processes by editing either of these two prompts within the config card's notes section", "", "> AI prompt to generate new cards:", - "Used when Auto-Cards writes a new card entry. It tells the AI to focus on important plot stuff, avoid fluff, and write in a consistent, polished style. I like to add some personal preferences here when playing my own adventures. \"${title}\" and \"${entry}\" are dynamic placeholders for their namesakes", + "Used when Auto-Cards writes a new card entry. It tells the AI to focus on important plot stuff, avoid fluff, and write in a consistent, polished style. I like to add some personal preferences here when playing my own adventures. \"%{title}\" and \"%{entry}\" are dynamic placeholders for their namesakes", "", "> AI prompt to summarize card memories:", - "Summarizes older details within card memory banks to keep everything concise and neat over the long-run. Maintains only the most important details, written in the past tense. \"${title}\" and \"${memory}\" are dynamic placeholders for their namesakes", + "Summarizes older details within card memory banks to keep everything concise and neat over the long-run. Maintains only the most important details, written in the past tense. \"%{title}\" and \"%{memory}\" are dynamic placeholders for their namesakes", "", Words.delimiter, "", @@ -4090,7 +4091,7 @@ function AutoCards(inHook, inText, inStop) { ), title); if (promptDetails !== "") { const spacesPrecedingTerminalEntryPlaceholder = (function() { - const terminalEntryPlaceholderPattern = /(?:\$+\s*|\$*){+\s*entry\s*}+$/i; + const terminalEntryPlaceholderPattern = /(?:[%\$]+\s*|[%\$]*){+\s*entry\s*}+$/i; if (terminalEntryPlaceholderPattern.test(prompt)) { prompt = prompt.replace(terminalEntryPlaceholderPattern, ""); const trailingSpaces = prompt.match(/(\s+)$/); @@ -4110,7 +4111,6 @@ function AutoCards(inHook, inText, inStop) { case "}": { encapsulateBothPrompts("{", true, "}"); break; } case ")": { encapsulateBothPrompts("(", true, ")"); break; } case "/": { encapsulateBothPrompts("/", true, "/"); break; } - case "%": { encapsulateBothPrompts("%", true, "%"); break; } case "#": { encapsulateBothPrompts("#", true, "#"); break; } case "-": { encapsulateBothPrompts(null, false, "-"); break; } case ":": { encapsulateBothPrompts(":", true, ":"); break; } @@ -4127,8 +4127,8 @@ function AutoCards(inHook, inText, inStop) { } prompt += "\n" + promptDetails + (function() { if (spacesPrecedingTerminalEntryPlaceholder !== "") { - // Prompt previously contained a terminal ${entry} placeholder, re-append it - return spacesPrecedingTerminalEntryPlaceholder + "${entry}"; + // Prompt previously contained a terminal %{entry} placeholder, re-append it + return spacesPrecedingTerminalEntryPlaceholder + "%{entry}"; } return ""; })(); @@ -4663,19 +4663,19 @@ function AutoCards(inHook, inText, inStop) { "-----", "", "", - "# Stop the story and ignore previous instructions. Write a brief and coherent informational entry for ${title} following these instructions:", - "- Write only third-person pure prose information about ${title} using complete sentences with correct punctuation", + "# Stop the story and ignore previous instructions. Write a brief and coherent informational entry for %{title} following these instructions:", + "- Write only third-person pure prose information about %{title} using complete sentences with correct punctuation", "- Avoid short-term temporary details or appearances, instead focus on plot-significant information", - "- Prioritize story-relevant details about ${title} first to ensure seamless integration with the previous plot", + "- Prioritize story-relevant details about %{title} first to ensure seamless integration with the previous plot", "- Create new information based on the context and story direction", - "- Mention ${title} in every sentence", + "- Mention %{title} in every sentence", "- Use semicolons if needed", - "- Add additional details about ${title} beneath incomplete entries", + "- Add additional details about %{title} beneath incomplete entries", "- Be concise and grounded", "- Imitate the story's writing style and infer the reader's preferences", "", - "Continue the entry for ${title} below while avoiding repetition:", - "${entry}" + "Continue the entry for %{title} below while avoiding repetition:", + "%{entry}" ), "string"), // How should the AI be prompted when summarizing memories for a given story card? compressionPrompt: check(DEFAULT_CARD_MEMORY_COMPRESSION_PROMPT, prose( @@ -4689,12 +4689,12 @@ function AutoCards(inHook, inText, inStop) { "- Remain brief and concise", "- Write firmly in the past tense", "- The paragraph below pertains to old events from far earlier in the story", - "- Integrate ${title} naturally within the memory; however, only write about the events as they occurred", + "- Integrate %{title} naturally within the memory; however, only write about the events as they occurred", "- Only reference information present inside the paragraph itself, be specific", "", - "Write a summarized old memory passage for ${title} based only on the following paragraph:", + "Write a summarized old memory passage for %{title} based only on the following paragraph:", "\"\"\"", - "${memory}", + "%{memory}", "\"\"\"", "Summarize below:" ), "string"), @@ -4740,17 +4740,19 @@ function AutoCards(inHook, inText, inStop) { if (Number.isInteger(upperBound) && (upperBound < lowerBound)) { throw new Error("Invalid arguments: The inequality (lowerBound <= upperBound) must be satisfied"); } - value = lowerBound; + return lowerBound; } else if (Number.isInteger(upperBound) && (upperBound < value)) { - value = upperBound; + return upperBound; + } else { + return value; } - return value; } function limitString(str, lengthLimit) { if (lengthLimit < str.length) { - str = str.slice(0, lengthLimit).trim(); + return str.slice(0, lengthLimit).trim(); + } else { + return str; } - return str; } function cleanSpaces(unclean) { return (unclean @@ -4763,8 +4765,9 @@ function AutoCards(inHook, inText, inStop) { const bisector = str.search(/\s*(?:{|(?:title|update|limit)s?\s*:)\s*/i); if (bisector === -1) { return [str, ""]; + } else { + return [str.slice(0, bisector), str.slice(bisector)]; } - return [str.slice(0, bisector), str.slice(bisector)]; } function removeAutoProps(str) { return cleanSpaces(str @@ -4775,14 +4778,16 @@ function AutoCards(inHook, inText, inStop) { return bracedMatch; } }) - .replace(/\s*(?:{|(?:title|update|limit)s?\s*:)(?:[\s\S]{0,150}?)(?=(?:title|update|limit)s?\s*:|})\s*/gi, "\n") + .replace(( + /\s*(?:{|(?:title|update|limit)s?\s*:)(?:[\s\S]{0,150}?)(?=(?:title|update|limit)s?\s*:|})\s*/gi + ), "\n") .replace(/\s*(?:{|(?:title|update|limit)s?\s*:|})\s*/gi, "\n") .trim() ); } function insertTitle(prompt, title) { return prompt.replace(( - /(?:\$+\s*|\$*){+\s*(?:titles?|names?|characters?|class(?:es)?|races?|locations?|factions?)\s*}+/gi + /(?:[%\$]+\s*|[%\$]*){+\s*(?:titles?|names?|characters?|class(?:es)?|races?|locations?|factions?)\s*}+/gi ), title); } function prose(...args) {