### Start Llama.cpp Server Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/readme.md Use this command to start the Llama.cpp server. Adjust the model path and context size as needed for your setup. Ensure the port matches your SillyTavern configuration. ```shell llama-server -m -c --port 8080 ``` -------------------------------- ### Good Side Prompt: Stable Headings Example Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md An example of using stable, descriptive headings for a relationship tracker. ```markdown # Relationship Tracker ## Current Status ## Recent Changes ## Open Tensions ## Next Likely Developments ``` -------------------------------- ### Example Runtime Macro Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Demonstrates the basic syntax for a runtime macro placeholder. ```text {{npc name}} ``` -------------------------------- ### Bad Side Prompt: Unstable Heading Example Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md An example of a vague and overly verbose heading that is not suitable for stable updates. ```markdown # Here is my extensive and emotionally intelligent breakdown of everything that might be happening ``` -------------------------------- ### Recommended Macro Names Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Provides examples of recommended macro naming conventions for clarity and ease of use. ```text {{npc name}} {{npc_1}} {{faction}} {{project_name}} ``` -------------------------------- ### Install Git Hooks for Silly Tavern Memory Books Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/readme.md Install the pre-commit hook to automatically build the extension and include build artifacts in commits. This ensures code consistency. ```sh bun run install-hooks ``` -------------------------------- ### Weak Side Prompt Example Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md A basic and unspecific instruction for updating a tracker. ```text Update the relationship tracker. ``` -------------------------------- ### Better Side Prompt Example Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md A more detailed instruction for updating a tracker, specifying preservation, removal, and output format. ```text Update the relationship tracker. Preserve useful facts, remove resolved or obsolete details, and keep each entry to 1-3 concise bullets. Output only the updated tracker. ``` -------------------------------- ### Example Facts for Clips Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/USER_GUIDE.md These are examples of specific, discrete facts that are suitable for saving as Clips in a Memory Book. ```text Aiko likes honey tea. ``` ```text Andalino promised not to lie to her again. ``` ```text Colt calls her Boss. ``` -------------------------------- ### Example of a Focused Topical Clip Topic (Item) Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/USER_GUIDE.md Use narrow and specific topics for better AI focus. This example shows a good topic for a specific item. ```text The silver key ``` -------------------------------- ### Example of a Focused Topical Clip Topic Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/USER_GUIDE.md Use narrow and specific topics for better AI focus. This example shows a good topic for a relationship. ```text Alex and Mira's relationship ``` -------------------------------- ### Build the Silly Tavern Memory Books Extension Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/readme.md Use this command to build the extension, which minifies and bundles source files. This is part of the developer setup. ```sh bun run build ``` -------------------------------- ### Example of a Broad Topical Clip Topic (Item) Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/USER_GUIDE.md Avoid overly broad topics as they are less useful for AI focus. This example shows a less useful topic for items. ```text Important items ``` -------------------------------- ### Example Topics for Topical Clip Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/USER_GUIDE.md These are examples of subjects that can be used as topics when creating a Topical Clip to generate a focused memory entry. ```text Seraphina ``` ```text {{user}}'s magic ``` ```text Alex and Mira's relationship ``` ```text The Black Harbor investigation ``` ```text The silver key ``` -------------------------------- ### Example Clip Content Structure Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/USER_GUIDE.md This shows the internal structure of a clip entry, using a clean section format with a heading and content. ```md === Seraphina Healed Me === - Seraphina healed my wounds with magic. === END Seraphina Healed Me === ``` -------------------------------- ### Example Clip Entry Format Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/USER_GUIDE.md This is how a clip entry is marked within a lorebook entry. The tag '[STMB Clip]' identifies it. ```txt Seraphina Healed Me [STMB Clip] ``` -------------------------------- ### Example of a Broad Topical Clip Topic Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/USER_GUIDE.md Avoid overly broad topics as they are less useful for AI focus. This example shows a less useful topic for story elements. ```text Everything about the story ``` -------------------------------- ### Good Side Prompt Naming Convention: Faction Tracker Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md An example of a clear and descriptive macro name for a faction tracker, including a placeholder. ```text Faction Tracker - {{faction}} ``` -------------------------------- ### Good Side Prompt Naming Convention: Relationship Tracker Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md An example of a clear and descriptive macro name for a relationship tracker, including a placeholder. ```text Relationship Tracker - {{npc name}} ``` -------------------------------- ### JSON-Only Output Example Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/readme.md Instructs the AI to return only valid JSON for memory generation. Ensure no other text is included in the response. ```json { "title": "Short scene title", "content": "Detailed summary of the scene...", "keywords": ["keyword1", "keyword2"] } ``` -------------------------------- ### Create Memory from Marked Scene Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/USER_GUIDE.md Use the /creatememory command to generate a memory from messages that have been manually marked as a scene. This requires prior selection of the scene's start and end points. ```bash /creatememory ``` -------------------------------- ### Example Entry Title for New Topical Clip Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/USER_GUIDE.md This shows the format of a new memory entry created using the Topical Clip feature, specifically when the topic is 'Seraphina'. ```text About Seraphina [STMB Clip] ``` -------------------------------- ### Good Side Prompt Naming Convention: NPC Status Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md An example of a clear and descriptive macro name for tracking NPC status, including a placeholder. ```text NPC Status - {{npc name}} ``` -------------------------------- ### Example Clip Entry Content Structure Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/readme.md This shows the markdown structure for the visible content within a clip entry. The section title is derived from the entry title, excluding the '[STMB Clip]' tag. ```markdown === Seraphina Healed Me === - Seraphina healed my wounds with magic. - Seraphina, guardian of this forest === END Seraphina Healed Me === ``` -------------------------------- ### Manual Side Prompt Run with Macro Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Shows how to manually execute a Side Prompt and provide a value for a runtime macro. ```text /sideprompt "Relationship Tracker" {{npc name}}="Alice" ``` -------------------------------- ### Running Side Prompt with Macro Set Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Shows how to run a Side Prompt using a macro set and providing values for its macros. ```text /sideprompt-macroset "Relationship Pass" {{npc_1}}="Alice" ``` -------------------------------- ### Initialize and Event Listeners for Memorybooks Toggle Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/resources/stmb-toggle.html Sets up initial DOM element references and event listeners for file input, processing, and downloading. Handles file loading, JSON parsing, and error display. ```javascript (function () { const fileInput = document.getElementById('fileInput'); const processBtn = document.getElementById('processBtn'); const downloadBtn = document.getElementById('downloadBtn'); const statusEl = document.getElementById('status'); const outputEl = document.getElementById('output'); let originalFilename = ''; let parsedJson = null; let modifiedJson = null; function setStatus(msg, isError = false) { statusEl.textContent = msg; statusEl.classList.toggle('error', isError); } function pretty(obj) { try { return JSON.stringify(obj); } catch (e) { return String(e); } } function deepClone(obj) { // Good enough for plain JSON data return JSON.parse(JSON.stringify(obj)); } function processData() { if (!parsedJson) { setStatus('No JSON loaded to process.', true); return; } const working = deepClone(parsedJson); if (typeof working !== 'object' || working === null) { setStatus('Top-level JSON is not an object.', true); return; } const { entries } = working; if (typeof entries !== 'object' || entries === null) { setStatus('Missing or invalid "entries" object in JSON.', true); return; } let targetedEntries = 0; let flippedDelay = 0; let flippedPrevent = 0; for (const [k, entry] of Object.entries(entries)) { if (entry && entry.stmemorybooks === true) { targetedEntries++; if (entry.delayUntilRecursion === false) { entry.delayUntilRecursion = true; flippedDelay++; } if (entry.preventRecursion === true) { entry.preventRecursion = false; flippedPrevent++; } } } modifiedJson = working; outputEl.value = pretty(modifiedJson); const lines = [ 'Processed successfully.', `Targeted entries (stmemorybooks === true): ${targetedEntries}`, `Flipped delayUntilRecursion (false → true): ${flippedDelay}`, `Flipped preventRecursion (true → false): ${flippedPrevent}`, `Original filename: ${originalFilename || '(unknown)'}`, ]; setStatus(lines.join('\n'), false); downloadBtn.disabled = false; } function inferModifiedName(name) { if (!name) return 'modified.json'; const i = name.toLowerCase().lastIndexOf('.json'); if (i > 0) { return name.slice(0, i) + '-modified.json'; } return name + '-modified.json'; } function handleDownload() { if (!modifiedJson) { setStatus('Nothing to download yet. Process a file first.', true); return; } const blob = new Blob([pretty(modifiedJson)], { type: 'application/json;charset=utf-8' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = inferModifiedName(originalFilename); document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url); } function handleFile(e) { const file = e.target.files && e.target.files[0]; if (!file) { parsedJson = null; modifiedJson = null; processBtn.disabled = true; downloadBtn.disabled = true; outputEl.value = ''; setStatus('No file loaded.'); return; } originalFilename = file.name || ''; const reader = new FileReader(); reader.onerror = () => { parsedJson = null; processBtn.disabled = true; downloadBtn.disabled = true; setStatus('Failed to read file.', true); }; reader.onload = () => { try { const text = String(reader.result || ''); parsedJson = JSON.parse(text); modifiedJson = null; outputEl.value = ''; setStatus(`File loaded: ${originalFilename} Ready to process.`); processBtn.disabled = false; downloadBtn.disabled = true; } catch (err) { parsedJson = null; modifiedJson = null; processBtn.disabled = true; downloadBtn.disabled = true; outputEl.value = ''; setStatus('Invalid JSON: ' + err.message, true); } }; reader.readAsText(file, 'utf-8'); } fileInput.addEventListener('change', handleFile); processBtn.addEventListener('click', processData); downloadBtn.addEventListener('click', handleDownload); })(); ``` -------------------------------- ### Run a Reusable Side Prompt Set with Macros Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Use `/sideprompt-macroset` to run a set that requires specific macro values to be provided at runtime. ```text /sideprompt-macroset "Relationship Pass" {{npc_1}}="Alice" {{npc_2}}="Bob" 10-20 ``` -------------------------------- ### Invention or Project Tracker Prompt Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Use this prompt to update a project tracker, focusing on meaningful changes in goal, progress, blockers, scope, dependencies, or story relevance. Entries should be concise and ordered by introduction. ```txt Update the project tracker. Track only meaningful changes in goal, progress, blockers, scope, dependencies, or story relevance. Keep entries concise and ordered by first introduction. ``` -------------------------------- ### Storing Set Value for Macro Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Illustrates how to store a value for a macro within a set. ```text {{npc name}} = Alice ``` -------------------------------- ### Run Side Prompt with Macros and Range Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/USER_GUIDE.md Execute a side prompt with optional runtime macros and a message range using the /sideprompt command. This allows for dynamic content generation or analysis based on specific chat segments. ```bash /sideprompt "Relationship Tracker" {{macro}}="value" [X-Y] ``` -------------------------------- ### Lorebook Converter Main Logic Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/resources/lorebookconverter.html Handles file uploads, conversion triggers, and event listeners for UI elements. It orchestrates the entire conversion process from file input to download. ```javascript document.addEventListener('DOMContentLoaded', () => { const uploadInput = document.getElementById('jsonUpload'); const convertBtn = document.getElementById('convertBtn'); const fileNameDisplay = document.getElementById('fileName'); const downloadLinkContainer = document.getElementById('downloadLinkContainer'); const downloadLink = document.getElementById('downloadLink'); const sampleTitleInput = document.getElementById('sampleTitleInput'); const regexDisplay = document.getElementById('regexDisplay'); let uploadedFile = null; uploadInput.addEventListener('change', (event) => { if (event.target.files.length > 0) { uploadedFile = event.target.files[0]; fileNameDisplay.textContent = uploadedFile.name; convertBtn.classList.add('enabled'); } else { uploadedFile = null; fileNameDisplay.textContent = ''; convertBtn.classList.remove('enabled'); } }); sampleTitleInput.addEventListener('input', () => { const sample = sampleTitleInput.value; if (sample) { const regex = createRegexFromSample(sample); regexDisplay.textContent = regex.toString(); } else { regexDisplay.textContent = ''; } }); convertBtn.addEventListener('click', () => { if (uploadedFile) { processFile(uploadedFile); } }); function processFile(file) { const reader = new FileReader(); reader.onload = (event) => { try { const lorebookData = JSON.parse(event.target.result); const convertedData = convertLorebook(lorebookData); const newFileName = file.name.replace('.json', '_converted.json'); triggerDownload(convertedData, newFileName); } catch (error) { alert(`Error processing file. Please ensure it is a valid JSON lorebook. Error: ${error.message}`); } }; reader.readAsText(file); } const escapeRegex = (str) => str.replace(/[\[.*+?^${}()|[\]\\]/g, '\\$&'); const createLiteralPattern = (str) => escapeRegex(str).replace(/\s+/g, '\\s*'); function createRegexFromSample(sample) { const trimmedSample = sample.trim(); const numberMatch = trimmedSample.match(/\d+/); if (!numberMatch) { return new RegExp(`^${createLiteralPattern(trimmedSample)}$`); } const numberIndex = numberMatch.index; const numberLength = numberMatch[0].length; const numberPattern = numberLength === 1 ? '\\d+' : `\\d{${numberLength}}`; const prefix = trimmedSample.substring(0, numberIndex); const suffix = trimmedSample.substring(numberIndex + numberLength); const separatorMatch = suffix.match(/^[^A-Za-z0-9]*/); const separator = separatorMatch ? separatorMatch[0] : ''; const hasTrailingTitle = suffix.substring(separator.length).trim().length > 0; let pattern = `^${createLiteralPattern(prefix)}${numberPattern}`; if (separator) { pattern += createLiteralPattern(separator); } if (hasTrailingTitle) { pattern += '.+' } else if (suffix.trim()) { pattern += createLiteralPattern(suffix); } pattern += '$'; return new RegExp(pattern); } function convertLorebook(data) { if (!data || !data.entries) { throw new Error("Invalid lorebook structure: 'entries' object not found."); } const sample = sampleTitleInput.value.trim(); let isMemoryRegex; if (sample) { isMemoryRegex = createRegexFromSample(sample); regexDisplay.textContent = isMemoryRegex.toString(); } else { isMemoryRegex = /^\d+\s*-\s*.+/; regexDisplay.textContent = `Using default: ${isMemoryRegex.toString()}`; } let memoriesConverted = 0; const entries = Object.values(data.entries); const totalEntries = entries.length; entries.forEach(entry => { const entryTitle = typeof entry.comment === 'string' ? entry.comment.trim() : ''; const titleMatches = entryTitle && isMemoryRegex.test(entryTitle); if (titleMatches) { entry.stmemorybooks = true; memoriesConverted++; } }); alert(`Conversion complete. Checked ${totalEntries} entries and flagged ${memoriesConverted} as memories.`); return data; } function triggerDownload(data, filename) { const jsonStr = JSON.stringify(data, null, 4); const blob = new Blob([jsonStr], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; a.textContent = `Download ${filename}`; downloadLink.innerHTML = ''; downloadLink.appendChild(a); downloadLinkContainer.style.display = 'block'; } }); ``` -------------------------------- ### Instruct Model to Update and Clean Tracker Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Command the Side Prompt to refresh its tracker by removing obsolete speculation, resolved conflicts, and contradicted details. This ensures the tracker remains accurate. ```txt Update the tracker. Remove obsolete speculation, resolved conflicts, and details contradicted by the selected messages. ``` -------------------------------- ### Instruct Model to Merge and Remove Details Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Direct the model to consolidate related information and discard outdated or redundant details. This helps maintain concise and relevant output. ```txt Merge related details. Remove stale, resolved, or redundant details. ``` -------------------------------- ### Run a Side Prompt Manually Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Use the basic `/sideprompt` command to run a single Side Prompt by its name. ```text /sideprompt "Prompt Name" ``` -------------------------------- ### Run a Side Prompt with Runtime Macro Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Provide custom values for runtime macros within the Side Prompt command, such as setting an NPC's name. ```text /sideprompt "Relationship Tracker" {{npc name}}="Alice" 10-20 ``` -------------------------------- ### Reusable Cast Pass Macro Set Reuse Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Demonstrates reusing the 'Cast Pass' macro set with different character assignments. ```txt /sideprompt-macroset "Cast Pass" {{npc_1}}="Mira" {{npc_2}}="Jonas" ``` -------------------------------- ### Relationship Tracker Macro Set Rows Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Demonstrates setting rows for the Relationship Tracker side prompt using stored macros for different NPCs. ```md | Row | Side Prompt | Stored Macro | |---|---|---| | 1 | Relationship Tracker | `{{npc name}} = Alice` | | 2 | Relationship Tracker | `{{npc name}} = Bob` | ``` -------------------------------- ### Relationship Tracker Macro Prompt Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md This prompt uses a macro for NPC names to track relationships. It's designed to avoid creating separate prompt definitions for each NPC. ```txt /sideprompt "Relationship Tracker" {{npc name}}="Alice" 10-40 ``` -------------------------------- ### Run a Side Prompt Set Manually Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Execute an entire Side Prompt Set by its name using the `/sideprompt-set` command. ```text /sideprompt-set "Set Name" ``` -------------------------------- ### Side Prompt with Specific Message Range Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Illustrates how to execute a Side Prompt targeting a specific range of messages. ```text /sideprompt "Plot Points" 50-80 ``` -------------------------------- ### Run a Side Prompt with Message Range Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Specify a message range (e.g., 10-20) to limit the scope of the Side Prompt's execution. ```text /sideprompt "Prompt Name" 10-20 ``` -------------------------------- ### Consolidation Input Structure Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/howSTMBworks-en.md This is the rough structure of the input text provided to the model during consolidation. It includes the prompt, optional previous summaries, and the source entries. ```text [consolidation prompt / preset instructions] === PREVIOUS ARC/CHAPTER/BOOK (CANON - DO NOT REWRITE) === [optional previous higher-tier summary] === END PREVIOUS ... === === MEMORIES / ARCS / CHAPTERS === === memory 001 === Title: ... Contents: ... === end memory 001 === === memory 002 === Title: ... Contents: ... === end memory 002 === ... ``` -------------------------------- ### Reusable Set-Level Macro Value Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Demonstrates using a reusable set-level value to define another macro. ```text {{npc name}} = {{npc_1}} ``` -------------------------------- ### Plot Points Tracker Prompt Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Use this prompt to update a plot points tracker, focusing on active or recently resolved threads grouped by storyline. Output should be the updated tracker. ```txt Update the plot points tracker based on the selected messages. Keep only active or recently resolved threads. Group by storyline. Output only the updated tracker. ``` -------------------------------- ### Run a Side Prompt Set with Message Range Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md Specify a message range when running a Side Prompt Set to control the execution scope. ```text /sideprompt-set "Set Name" 10-20 ``` -------------------------------- ### Summarize Since Last Memory Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/USER_GUIDE.md The /nextmemory command summarizes all messages that have occurred since the last memory was created. This is useful for continuous narrative tracking. ```bash /nextmemory ``` -------------------------------- ### Reusable Cast Pass Macro Set Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md This prompt uses set-level runtime tokens to create a reusable cast pass. It allows for the same set to be used with different casts by changing the macro values. ```txt /sideprompt-macroset "Cast Pass" {{npc_1}}="Alice" {{npc_2}}="Bob" ``` -------------------------------- ### Yell at the AI in OOC Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/readme.md If the AI is not using provided information, use this OOC command to prompt it directly. This is a last resort after verifying entries are being sent. ```text [OOC: WHY are you not using the information you were given? Specifically: (whatever it was)] ``` -------------------------------- ### Create Memory from Message Range Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/USER_GUIDE.md Use the /scenememory command to create a memory from a specified range of messages. This is useful for capturing specific events or dialogues within a chat. ```bash /scenememory 10-25 ``` -------------------------------- ### Supported Placeholders in Topical Clip Prompt Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/USER_GUIDE.md These placeholders can be used in the Topical Clip prompt to dynamically insert relevant information. {{SOURCE_MEMORIES}} is required. ```text {{MODE}} ``` ```text {{TOPIC}} ``` ```text {{KEYWORDS}} ``` ```text {{EXISTING_CLIP}} ``` ```text {{EXISTING_ENTRY_CONTENT}} ``` ```text {{SOURCE_MEMORIES}} ``` -------------------------------- ### Required Placeholder in Topical Clip Prompt Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/USER_GUIDE.md The {{SOURCE_MEMORIES}} placeholder is mandatory in the Topical Clip prompt for STMB to function correctly. Ensure it is included. ```text {{SOURCE_MEMORIES}} ``` -------------------------------- ### STMB Memory Generation Prompt Structure Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/howSTMBworks-en.md This is the typical structure of a prompt sent to the model for memory generation. It includes the memory prompt, optional previous context, and the current scene transcript. ```text [memory prompt / preset instructions] === PREVIOUS SCENE CONTEXT (DO NOT PROCESS) === [zero or more earlier memories] === END PREVIOUS SCENE CONTEXT - PROCESS ONLY THE SCENE BELOW === === SCENE TRANSCRIPT === Alice: ... Bob: ... === END SCENE === ``` -------------------------------- ### STMB Memory Generation JSON Output Schema Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/howSTMBworks-en.md The expected JSON object format for a generated memory. Use the exact keys 'title', 'content', and 'keywords'. ```json { "title": "Short scene title", "content": "The actual memory text", "keywords": ["keyword1", "keyword2", "keyword3"] } ``` -------------------------------- ### Side Prompt Guardrail: Append New Section Source: https://github.com/aikohanasaki/sillytavern-memorybooks/blob/main/userguides/side-prompts-en.md A guardrail to prevent unnecessary appending of new sections and encourage merging updates. ```text Do not append a new section unless there is genuinely new information. Merge updates into existing entries when possible. ```