v3.2.0: Major update with JSON trackers, locking system, and UI improvements
This commit is contained in:
@@ -7,13 +7,15 @@ An immersive RPG extension for browsers that tracks character stats, scene infor
|
|||||||
|
|
||||||
## 🆕 What's New
|
## 🆕 What's New
|
||||||
|
|
||||||
### v3.1.1
|
### v3.2.0
|
||||||
|
|
||||||
- Mobile UI fixes.
|
- Mobile UI fixes (AGAIN).
|
||||||
|
- Fixed the regex issue in Together mode.
|
||||||
### v3.0.1
|
- Fixed the parsing error to not appear upon loading new chats or switching them.
|
||||||
|
- Fixed adding new relationships in the Edit Trackers.
|
||||||
- Small bug fix where you couldn't edit the thought bubble.
|
- Added migration for importing older trackers' presets.
|
||||||
|
- Lifted attributes' cap to 999.
|
||||||
|
- Fixed some mobile displays.
|
||||||
|
|
||||||
**Special thanks to all the other contributors for this project:**
|
**Special thanks to all the other contributors for this project:**
|
||||||
Paperboygold, Munimunigamer, Subarashimo, Lilminzyu, Claude, IDeathByte, Chungchandev, Joenunezb, and Amauragis.
|
Paperboygold, Munimunigamer, Subarashimo, Lilminzyu, Claude, IDeathByte, Chungchandev, Joenunezb, and Amauragis.
|
||||||
|
|||||||
@@ -315,6 +315,7 @@ async function initUI() {
|
|||||||
updateGenerationModeUI();
|
updateGenerationModeUI();
|
||||||
|
|
||||||
// Add or remove JSON cleaning regex based on mode
|
// Add or remove JSON cleaning regex based on mode
|
||||||
|
// This ensures old messages in chat history are also cleaned
|
||||||
try {
|
try {
|
||||||
if (extensionSettings.generationMode === 'together') {
|
if (extensionSettings.generationMode === 'together') {
|
||||||
await ensureJsonCleaningRegex(st_extension_settings, saveSettingsDebounced);
|
await ensureJsonCleaningRegex(st_extension_settings, saveSettingsDebounced);
|
||||||
@@ -1000,7 +1001,10 @@ jQuery(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Import the JSON cleaning regex for Together mode if enabled
|
// Import the JSON cleaning regex for Together mode if enabled
|
||||||
|
// This cleans historical messages when displayed
|
||||||
|
// Note: We also clean directly in message handler for redundancy
|
||||||
try {
|
try {
|
||||||
|
console.log('[RPG Companion] Checking JSON cleaning regex. Generation mode:', extensionSettings.generationMode);
|
||||||
if (extensionSettings.generationMode === 'together') {
|
if (extensionSettings.generationMode === 'together') {
|
||||||
await ensureJsonCleaningRegex(st_extension_settings, saveSettingsDebounced);
|
await ensureJsonCleaningRegex(st_extension_settings, saveSettingsDebounced);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-1
@@ -6,6 +6,6 @@
|
|||||||
"js": "index.js",
|
"js": "index.js",
|
||||||
"css": "style.css",
|
"css": "style.css",
|
||||||
"author": "Marinara",
|
"author": "Marinara",
|
||||||
"version": "3.1.0",
|
"version": "3.2.0",
|
||||||
"homePage": "https://github.com/SpicyMarinara/rpg-companion-sillytavern"
|
"homePage": "https://github.com/SpicyMarinara/rpg-companion-sillytavern"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="margin-top: 10px; text-align: center; opacity: 0.6; font-size: 0.85em;">
|
<div style="margin-top: 10px; text-align: center; opacity: 0.6; font-size: 0.85em;">
|
||||||
v3.1.1
|
v3.2.0
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+6
-6
@@ -111,11 +111,11 @@
|
|||||||
"template.trackerEditorModal.tabs.userStats": "User Stats",
|
"template.trackerEditorModal.tabs.userStats": "User Stats",
|
||||||
"template.trackerEditorModal.tabs.infoBox": "Info Box",
|
"template.trackerEditorModal.tabs.infoBox": "Info Box",
|
||||||
"template.trackerEditorModal.tabs.presentCharacters": "Present Characters",
|
"template.trackerEditorModal.tabs.presentCharacters": "Present Characters",
|
||||||
"template.trackerEditorModal.buttons.reset": "Reset to Defaults",
|
"template.trackerEditorModal.buttons.reset": "Reset",
|
||||||
"template.trackerEditorModal.buttons.cancel": "Cancel",
|
"template.trackerEditorModal.buttons.cancel": "Cancel",
|
||||||
"template.trackerEditorModal.buttons.save": "Save & Apply",
|
"template.trackerEditorModal.buttons.save": "Save & Apply",
|
||||||
"template.trackerEditorModal.buttons.export": "Export Preset",
|
"template.trackerEditorModal.buttons.export": "Export",
|
||||||
"template.trackerEditorModal.buttons.import": "Import Preset",
|
"template.trackerEditorModal.buttons.import": "Import",
|
||||||
"template.trackerEditorModal.messages.exportSuccess": "Tracker preset exported successfully!",
|
"template.trackerEditorModal.messages.exportSuccess": "Tracker preset exported successfully!",
|
||||||
"template.trackerEditorModal.messages.exportError": "Failed to export tracker preset. Check console for details.",
|
"template.trackerEditorModal.messages.exportError": "Failed to export tracker preset. Check console for details.",
|
||||||
"template.trackerEditorModal.messages.importSuccess": "Tracker preset imported successfully!",
|
"template.trackerEditorModal.messages.importSuccess": "Tracker preset imported successfully!",
|
||||||
@@ -145,10 +145,10 @@
|
|||||||
"template.trackerEditorModal.infoBoxTab.recentEventsWidget": "Recent Events",
|
"template.trackerEditorModal.infoBoxTab.recentEventsWidget": "Recent Events",
|
||||||
"template.trackerEditorModal.presentCharactersTab.relationshipStatusTitle": "Relationship Status Fields",
|
"template.trackerEditorModal.presentCharactersTab.relationshipStatusTitle": "Relationship Status Fields",
|
||||||
"template.trackerEditorModal.presentCharactersTab.enableRelationshipStatus": "Enable Relationship Status Fields",
|
"template.trackerEditorModal.presentCharactersTab.enableRelationshipStatus": "Enable Relationship Status Fields",
|
||||||
"template.trackerEditorModal.presentCharactersTab.relationshipStatusHint": "Define relationship types with corresponding emojis shown on character portraits",
|
"template.trackerEditorModal.presentCharactersTab.relationshipStatusHint": "Define relationship types with corresponding emojis shown on character portraits.",
|
||||||
"template.trackerEditorModal.presentCharactersTab.newRelationshipButton": "New Relationship",
|
"template.trackerEditorModal.presentCharactersTab.newRelationshipButton": "New Relationship",
|
||||||
"template.trackerEditorModal.presentCharactersTab.appearanceDemeanorTitle": "Appearance/Demeanor Fields",
|
"template.trackerEditorModal.presentCharactersTab.appearanceDemeanorTitle": "Appearance/Demeanor Fields",
|
||||||
"template.trackerEditorModal.presentCharactersTab.appearanceDemeanorHint": "Fields shown below character name, separated by |",
|
"template.trackerEditorModal.presentCharactersTab.appearanceDemeanorHint": "Fields shown below character name.",
|
||||||
"template.trackerEditorModal.presentCharactersTab.addCustomFieldButton": "Add Custom Field",
|
"template.trackerEditorModal.presentCharactersTab.addCustomFieldButton": "Add Custom Field",
|
||||||
"template.trackerEditorModal.presentCharactersTab.thoughtsConfigTitle": "Thoughts Configuration",
|
"template.trackerEditorModal.presentCharactersTab.thoughtsConfigTitle": "Thoughts Configuration",
|
||||||
"template.trackerEditorModal.presentCharactersTab.enableCharacterThoughts": "Enable Character Thoughts",
|
"template.trackerEditorModal.presentCharactersTab.enableCharacterThoughts": "Enable Character Thoughts",
|
||||||
@@ -156,7 +156,7 @@
|
|||||||
"template.trackerEditorModal.presentCharactersTab.aiInstructionLabel": "AI Instruction:",
|
"template.trackerEditorModal.presentCharactersTab.aiInstructionLabel": "AI Instruction:",
|
||||||
"template.trackerEditorModal.presentCharactersTab.characterStatsTitle": "Character Stats",
|
"template.trackerEditorModal.presentCharactersTab.characterStatsTitle": "Character Stats",
|
||||||
"template.trackerEditorModal.presentCharactersTab.trackCharacterStats": "Track Character Stats",
|
"template.trackerEditorModal.presentCharactersTab.trackCharacterStats": "Track Character Stats",
|
||||||
"template.trackerEditorModal.presentCharactersTab.characterStatsHint": "Create stats to track for each character (displayed as colored bars)",
|
"template.trackerEditorModal.presentCharactersTab.characterStatsHint": "Create stats to track for each character (displayed as colored bars).",
|
||||||
"template.trackerEditorModal.presentCharactersTab.addCharacterStatButton": "Add Character Stat",
|
"template.trackerEditorModal.presentCharactersTab.addCharacterStatButton": "Add Character Stat",
|
||||||
"template.mainPanel.title": "RPG Companion",
|
"template.mainPanel.title": "RPG Companion",
|
||||||
"template.mainPanel.lastRoll": "Last Roll:",
|
"template.mainPanel.lastRoll": "Last Roll:",
|
||||||
|
|||||||
+3
-3
@@ -81,11 +81,11 @@
|
|||||||
"template.trackerEditorModal.tabs.userStats": "User 屬性",
|
"template.trackerEditorModal.tabs.userStats": "User 屬性",
|
||||||
"template.trackerEditorModal.tabs.infoBox": "資訊框",
|
"template.trackerEditorModal.tabs.infoBox": "資訊框",
|
||||||
"template.trackerEditorModal.tabs.presentCharacters": "在場角色",
|
"template.trackerEditorModal.tabs.presentCharacters": "在場角色",
|
||||||
"template.trackerEditorModal.buttons.reset": "重置為預設值",
|
"template.trackerEditorModal.buttons.reset": "重置",
|
||||||
"template.trackerEditorModal.buttons.cancel": "取消",
|
"template.trackerEditorModal.buttons.cancel": "取消",
|
||||||
"template.trackerEditorModal.buttons.save": "保存並應用",
|
"template.trackerEditorModal.buttons.save": "保存並應用",
|
||||||
"template.trackerEditorModal.buttons.export": "匯出預設",
|
"template.trackerEditorModal.buttons.export": "匯出",
|
||||||
"template.trackerEditorModal.buttons.import": "匯入預設",
|
"template.trackerEditorModal.buttons.import": "匯入",
|
||||||
"template.trackerEditorModal.messages.exportSuccess": "追蹤器預設匯出成功!",
|
"template.trackerEditorModal.messages.exportSuccess": "追蹤器預設匯出成功!",
|
||||||
"template.trackerEditorModal.messages.exportError": "匯出追蹤器預設失敗。請檢查控制台以獲取詳細資訊。",
|
"template.trackerEditorModal.messages.exportError": "匯出追蹤器預設失敗。請檢查控制台以獲取詳細資訊。",
|
||||||
"template.trackerEditorModal.messages.importSuccess": "追蹤器預設匯入成功!",
|
"template.trackerEditorModal.messages.importSuccess": "追蹤器預設匯入成功!",
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export function setupClassicStatsButtons() {
|
|||||||
// Delegated event listener for increase buttons
|
// Delegated event listener for increase buttons
|
||||||
$userStatsContainer.on('click', '.rpg-stat-increase', function() {
|
$userStatsContainer.on('click', '.rpg-stat-increase', function() {
|
||||||
const stat = $(this).data('stat');
|
const stat = $(this).data('stat');
|
||||||
if (extensionSettings.classicStats[stat] < 100) {
|
if (extensionSettings.classicStats[stat] < 999) {
|
||||||
extensionSettings.classicStats[stat]++;
|
extensionSettings.classicStats[stat]++;
|
||||||
saveSettings();
|
saveSettings();
|
||||||
saveChatData();
|
saveChatData();
|
||||||
|
|||||||
@@ -27,17 +27,52 @@ export async function ensureJsonCleaningRegex(st_extension_settings, saveSetting
|
|||||||
st_extension_settings.regex = [];
|
st_extension_settings.regex = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const alreadyExists = existingScripts.some(script =>
|
const existingScript = existingScripts.find(script =>
|
||||||
script && script.scriptName && script.scriptName === scriptName
|
script && script.scriptName && script.scriptName === scriptName
|
||||||
);
|
);
|
||||||
|
|
||||||
if (alreadyExists) {
|
if (existingScript) {
|
||||||
// console.log('[RPG Companion] JSON cleaning regex already exists, skipping import');
|
// Update existing script with new regex pattern if it's different
|
||||||
|
const newPattern = '/```json[\\s\\S]*?```/gim';
|
||||||
|
|
||||||
|
if (existingScript.findRegex !== newPattern) {
|
||||||
|
existingScript.findRegex = newPattern;
|
||||||
|
existingScript.placement = [2]; // 2 = AI Output
|
||||||
|
existingScript.disabled = false; // Ensure it's enabled
|
||||||
|
existingScript.runOnEdit = true; // Ensure it runs on edit
|
||||||
|
existingScript.displayOnly = true; // Alter Chat Display
|
||||||
|
existingScript.onlyFormatDisplay = true; // Ensure display formatting is enabled
|
||||||
|
|
||||||
|
if (typeof saveSettingsDebounced === 'function') {
|
||||||
|
saveSettingsDebounced();
|
||||||
|
}
|
||||||
|
console.log('[RPG Companion] Updated regex pattern and placement.');
|
||||||
|
} else {
|
||||||
|
// Ensure it's enabled even if pattern matches
|
||||||
|
if (existingScript.disabled) {
|
||||||
|
existingScript.disabled = false;
|
||||||
|
if (typeof saveSettingsDebounced === 'function') {
|
||||||
|
saveSettingsDebounced();
|
||||||
|
}
|
||||||
|
console.log('[RPG Companion] Re-enabled disabled regex.');
|
||||||
|
} else {
|
||||||
|
// Also update placement if it's wrong
|
||||||
|
const expectedPlacement = [2]; // 2 = AI Output
|
||||||
|
if (JSON.stringify(existingScript.placement) !== JSON.stringify(expectedPlacement)) {
|
||||||
|
existingScript.placement = expectedPlacement;
|
||||||
|
if (typeof saveSettingsDebounced === 'function') {
|
||||||
|
saveSettingsDebounced();
|
||||||
|
// Force immediate save after a short delay
|
||||||
|
setTimeout(() => saveSettingsDebounced(), 100);
|
||||||
|
}
|
||||||
|
console.log('[RPG Companion] Updated regex placement to [2].');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log('[RPG Companion] JSON Cleaning Regex is already downloaded and active.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('[RPG Companion] Importing JSON cleaning regex for Together mode...');
|
|
||||||
|
|
||||||
// Generate a UUID for the script
|
// Generate a UUID for the script
|
||||||
const uuidv4 = () => {
|
const uuidv4 = () => {
|
||||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||||
@@ -50,19 +85,22 @@ export async function ensureJsonCleaningRegex(st_extension_settings, saveSetting
|
|||||||
// Create the regex script object for cleaning JSON tracker data
|
// Create the regex script object for cleaning JSON tracker data
|
||||||
// This regex matches ```json...``` code blocks containing tracker data
|
// This regex matches ```json...``` code blocks containing tracker data
|
||||||
// The prompt now explicitly instructs models to use this format
|
// The prompt now explicitly instructs models to use this format
|
||||||
|
// Updated to handle various whitespace scenarios and ensure it catches all variations
|
||||||
const regexScript = {
|
const regexScript = {
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
scriptName: scriptName,
|
scriptName: scriptName,
|
||||||
// Match ```json...``` code blocks (non-greedy, multiline)
|
// Match ```json...``` code blocks (handles spaces, newlines, any content)
|
||||||
// This is now the guaranteed format since prompts instruct models to use code blocks
|
// Using a more permissive pattern to catch all variations
|
||||||
findRegex: '/```json\\s*[\\s\\S]*?```/gi',
|
findRegex: '/```json[\\s\\S]*?```/gim',
|
||||||
replaceString: '',
|
replaceString: '',
|
||||||
trimStrings: [],
|
trimStrings: [],
|
||||||
placement: [0], // 0 = Output (transforms after generation, before display)
|
placement: [2], // 2 = AI Output
|
||||||
disabled: false,
|
disabled: false,
|
||||||
markdownOnly: false,
|
markdownOnly: false,
|
||||||
promptOnly: false, // Apply to both prompts and outputs
|
promptOnly: false,
|
||||||
runOnEdit: true,
|
runOnEdit: true,
|
||||||
|
displayOnly: true, // Alter Chat Display
|
||||||
|
onlyFormatDisplay: true, // Ensure display formatting is enabled
|
||||||
substituteRegex: 0,
|
substituteRegex: 0,
|
||||||
minDepth: null,
|
minDepth: null,
|
||||||
maxDepth: null
|
maxDepth: null
|
||||||
@@ -74,6 +112,7 @@ export async function ensureJsonCleaningRegex(st_extension_settings, saveSetting
|
|||||||
}
|
}
|
||||||
|
|
||||||
st_extension_settings.regex.push(regexScript);
|
st_extension_settings.regex.push(regexScript);
|
||||||
|
console.log('[RPG Companion] JSON Cleaning Regex created and activated.');
|
||||||
|
|
||||||
// Save the changes
|
// Save the changes
|
||||||
if (typeof saveSettingsDebounced === 'function') {
|
if (typeof saveSettingsDebounced === 'function') {
|
||||||
@@ -81,11 +120,8 @@ export async function ensureJsonCleaningRegex(st_extension_settings, saveSetting
|
|||||||
} else {
|
} else {
|
||||||
console.warn('[RPG Companion] saveSettingsDebounced is not a function, cannot save JSON cleaning regex');
|
console.warn('[RPG Companion] saveSettingsDebounced is not a function, cannot save JSON cleaning regex');
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('[RPG Companion] ✅ JSON cleaning regex imported successfully');
|
|
||||||
// console.log('[RPG Companion] This regex will automatically remove tracker JSON from Together mode messages');
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[RPG Companion] Failed to import JSON cleaning regex:', error);
|
console.error('[RPG Companion] JSON Cleaning Regex failed to properly initialize!');
|
||||||
console.error('[RPG Companion] Error details:', error.message, error.stack);
|
console.error('[RPG Companion] Error details:', error.message, error.stack);
|
||||||
// Don't throw - continue without it
|
// Don't throw - continue without it
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -295,8 +295,8 @@ export async function onGenerationStarted(type, data, dryRun) {
|
|||||||
// Clear Spotify prompt if disabled
|
// Clear Spotify prompt if disabled
|
||||||
setExtensionPrompt('rpg-companion-spotify', '', extension_prompt_types.IN_CHAT, 0, false);
|
setExtensionPrompt('rpg-companion-spotify', '', extension_prompt_types.IN_CHAT, 0, false);
|
||||||
}
|
}
|
||||||
} else if (extensionSettings.generationMode === 'separate') {
|
} else if (extensionSettings.generationMode === 'separate' || extensionSettings.generationMode === 'external') {
|
||||||
// In SEPARATE mode, inject the contextual summary for main roleplay generation
|
// In SEPARATE and EXTERNAL modes, inject the contextual summary for main roleplay generation
|
||||||
const contextSummary = generateContextualSummary();
|
const contextSummary = generateContextualSummary();
|
||||||
|
|
||||||
if (contextSummary) {
|
if (contextSummary) {
|
||||||
@@ -312,7 +312,7 @@ Ensure these details naturally reflect and influence the narrative. Character be
|
|||||||
if (!shouldSuppress) {
|
if (!shouldSuppress) {
|
||||||
setExtensionPrompt('rpg-companion-context', wrappedContext, extension_prompt_types.IN_CHAT, 1, false);
|
setExtensionPrompt('rpg-companion-context', wrappedContext, extension_prompt_types.IN_CHAT, 1, false);
|
||||||
}
|
}
|
||||||
// console.log('[RPG Companion] Injected contextual summary for separate mode:', contextSummary);
|
// console.log('[RPG Companion] Injected contextual summary for separate/external mode:', contextSummary);
|
||||||
} else {
|
} else {
|
||||||
// Clear if no data yet
|
// Clear if no data yet
|
||||||
setExtensionPrompt('rpg-companion-context', '', extension_prompt_types.IN_CHAT, 1, false);
|
setExtensionPrompt('rpg-companion-context', '', extension_prompt_types.IN_CHAT, 1, false);
|
||||||
@@ -325,7 +325,7 @@ Ensure these details naturally reflect and influence the narrative. Character be
|
|||||||
const htmlPrompt = `\n${htmlPromptText}`;
|
const htmlPrompt = `\n${htmlPromptText}`;
|
||||||
|
|
||||||
setExtensionPrompt('rpg-companion-html', htmlPrompt, extension_prompt_types.IN_CHAT, 0, false);
|
setExtensionPrompt('rpg-companion-html', htmlPrompt, extension_prompt_types.IN_CHAT, 0, false);
|
||||||
// console.log('[RPG Companion] Injected HTML prompt at depth 0 for separate mode');
|
// console.log('[RPG Companion] Injected HTML prompt at depth 0 for separate/external mode');
|
||||||
} else {
|
} else {
|
||||||
// Clear HTML prompt if disabled
|
// Clear HTML prompt if disabled
|
||||||
setExtensionPrompt('rpg-companion-html', '', extension_prompt_types.IN_CHAT, 0, false);
|
setExtensionPrompt('rpg-companion-html', '', extension_prompt_types.IN_CHAT, 0, false);
|
||||||
@@ -338,7 +338,7 @@ Ensure these details naturally reflect and influence the narrative. Character be
|
|||||||
const spotifyPrompt = `\n${spotifyPromptText} ${SPOTIFY_FORMAT_INSTRUCTION}`;
|
const spotifyPrompt = `\n${spotifyPromptText} ${SPOTIFY_FORMAT_INSTRUCTION}`;
|
||||||
|
|
||||||
setExtensionPrompt('rpg-companion-spotify', spotifyPrompt, extension_prompt_types.IN_CHAT, 0, false);
|
setExtensionPrompt('rpg-companion-spotify', spotifyPrompt, extension_prompt_types.IN_CHAT, 0, false);
|
||||||
// console.log('[RPG Companion] Injected Spotify prompt at depth 0 for separate mode');
|
// console.log('[RPG Companion] Injected Spotify prompt at depth 0 for separate/external mode');
|
||||||
} else {
|
} else {
|
||||||
// Clear Spotify prompt if disabled
|
// Clear Spotify prompt if disabled
|
||||||
setExtensionPrompt('rpg-companion-spotify', '', extension_prompt_types.IN_CHAT, 0, false);
|
setExtensionPrompt('rpg-companion-spotify', '', extension_prompt_types.IN_CHAT, 0, false);
|
||||||
|
|||||||
@@ -140,10 +140,8 @@ export async function onMessageReceived(data) {
|
|||||||
const responseText = lastMessage.mes;
|
const responseText = lastMessage.mes;
|
||||||
const parsedData = parseResponse(responseText);
|
const parsedData = parseResponse(responseText);
|
||||||
|
|
||||||
// Check if parsing completely failed (no tracker data found)
|
// Note: Don't show parsing error here - this event fires when loading chat history too
|
||||||
if (parsedData.parsingFailed) {
|
// Error notification is handled in apiClient.js for fresh generations only
|
||||||
toastr.error(i18n.getTranslation('errors.parsingError'), '', { timeOut: 5000 });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove locks from parsed data (JSON format only, text format is unaffected)
|
// Remove locks from parsed data (JSON format only, text format is unaffected)
|
||||||
if (parsedData.userStats) {
|
if (parsedData.userStats) {
|
||||||
@@ -195,7 +193,9 @@ export async function onMessageReceived(data) {
|
|||||||
// Only remove trackers if saveTrackerHistory is disabled
|
// Only remove trackers if saveTrackerHistory is disabled
|
||||||
// When enabled, trackers are in <trackers> XML tags which SillyTavern auto-hides
|
// When enabled, trackers are in <trackers> XML tags which SillyTavern auto-hides
|
||||||
if (!extensionSettings.saveTrackerHistory) {
|
if (!extensionSettings.saveTrackerHistory) {
|
||||||
// Remove all code blocks that contain tracker data
|
// Note: JSON code blocks are hidden from display by regex script (but preserved in message data)
|
||||||
|
|
||||||
|
// Remove old text format code blocks (legacy support)
|
||||||
cleanedMessage = cleanedMessage.replace(/```[^`]*?Stats\s*\n\s*---[^`]*?```\s*/gi, '');
|
cleanedMessage = cleanedMessage.replace(/```[^`]*?Stats\s*\n\s*---[^`]*?```\s*/gi, '');
|
||||||
cleanedMessage = cleanedMessage.replace(/```[^`]*?Info Box\s*\n\s*---[^`]*?```\s*/gi, '');
|
cleanedMessage = cleanedMessage.replace(/```[^`]*?Info Box\s*\n\s*---[^`]*?```\s*/gi, '');
|
||||||
cleanedMessage = cleanedMessage.replace(/```[^`]*?Present Characters\s*\n\s*---[^`]*?```\s*/gi, '');
|
cleanedMessage = cleanedMessage.replace(/```[^`]*?Present Characters\s*\n\s*---[^`]*?```\s*/gi, '');
|
||||||
|
|||||||
@@ -443,10 +443,10 @@ export function updateGenerationModeUI() {
|
|||||||
// Show auto-update toggle
|
// Show auto-update toggle
|
||||||
$('#rpg-auto-update-container').slideDown(200);
|
$('#rpg-auto-update-container').slideDown(200);
|
||||||
} else if (extensionSettings.generationMode === 'external') {
|
} else if (extensionSettings.generationMode === 'external') {
|
||||||
// In "external" mode, manual update button is visible AND external settings are shown
|
// In "external" mode, manual update button is visible AND both settings are shown
|
||||||
$('#rpg-manual-update').show();
|
$('#rpg-manual-update').show();
|
||||||
$('#rpg-external-api-settings').slideDown(200);
|
$('#rpg-external-api-settings').slideDown(200);
|
||||||
$('#rpg-separate-mode-settings').slideUp(200);
|
$('#rpg-separate-mode-settings').slideDown(200);
|
||||||
// Show auto-update toggle for external mode too
|
// Show auto-update toggle for external mode too
|
||||||
$('#rpg-auto-update-container').slideDown(200);
|
$('#rpg-auto-update-container').slideDown(200);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,6 +251,48 @@ function exportTrackerPreset() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrates old tracker preset format to current format
|
||||||
|
* @param {Object} config - The tracker config to migrate
|
||||||
|
* @returns {Object} - Migrated tracker config
|
||||||
|
*/
|
||||||
|
function migrateTrackerPreset(config) {
|
||||||
|
// Create a deep copy to avoid modifying the original
|
||||||
|
const migrated = JSON.parse(JSON.stringify(config));
|
||||||
|
|
||||||
|
// Migrate relationships structure (v3.0.0 -> v3.1.0)
|
||||||
|
if (migrated.presentCharacters) {
|
||||||
|
// Old format: relationshipEmojis directly on presentCharacters
|
||||||
|
// New format: relationships.relationshipEmojis
|
||||||
|
if (migrated.presentCharacters.relationshipEmojis &&
|
||||||
|
!migrated.presentCharacters.relationships) {
|
||||||
|
migrated.presentCharacters.relationships = {
|
||||||
|
enabled: migrated.presentCharacters.enableRelationships || true,
|
||||||
|
relationshipEmojis: migrated.presentCharacters.relationshipEmojis
|
||||||
|
};
|
||||||
|
// Keep legacy fields for backward compatibility
|
||||||
|
migrated.presentCharacters.relationshipFields = Object.keys(migrated.presentCharacters.relationshipEmojis);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure relationships object exists
|
||||||
|
if (!migrated.presentCharacters.relationships) {
|
||||||
|
migrated.presentCharacters.relationships = {
|
||||||
|
enabled: false,
|
||||||
|
relationshipEmojis: {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure relationshipEmojis exists within relationships
|
||||||
|
if (!migrated.presentCharacters.relationships.relationshipEmojis) {
|
||||||
|
migrated.presentCharacters.relationships.relationshipEmojis = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add any other migration logic here for future format changes
|
||||||
|
|
||||||
|
return migrated;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Import tracker configuration from a JSON file
|
* Import tracker configuration from a JSON file
|
||||||
*/
|
*/
|
||||||
@@ -278,6 +320,9 @@ function importTrackerPreset() {
|
|||||||
throw new Error('Invalid preset file: missing required configuration sections');
|
throw new Error('Invalid preset file: missing required configuration sections');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Migrate old preset format to current format
|
||||||
|
const migratedConfig = migrateTrackerPreset(data.trackerConfig);
|
||||||
|
|
||||||
// Ask for confirmation
|
// Ask for confirmation
|
||||||
const confirmMessage = i18n.getTranslation('template.trackerEditorModal.messages.importConfirm') ||
|
const confirmMessage = i18n.getTranslation('template.trackerEditorModal.messages.importConfirm') ||
|
||||||
'This will replace your current tracker configuration. Continue?';
|
'This will replace your current tracker configuration. Continue?';
|
||||||
@@ -286,8 +331,8 @@ function importTrackerPreset() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the imported configuration
|
// Apply the migrated configuration
|
||||||
extensionSettings.trackerConfig = JSON.parse(JSON.stringify(data.trackerConfig)); // Deep copy
|
extensionSettings.trackerConfig = migratedConfig;
|
||||||
|
|
||||||
// Re-render the editor UI
|
// Re-render the editor UI
|
||||||
renderEditorUI();
|
renderEditorUI();
|
||||||
@@ -794,14 +839,25 @@ function setupPresentCharactersListeners() {
|
|||||||
extensionSettings.trackerConfig.presentCharacters.relationships.relationshipEmojis = {};
|
extensionSettings.trackerConfig.presentCharacters.relationships.relationshipEmojis = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate a unique relationship name
|
||||||
|
let baseName = 'New Relationship';
|
||||||
|
let relationshipName = baseName;
|
||||||
|
let counter = 1;
|
||||||
|
const existingRelationships = extensionSettings.trackerConfig.presentCharacters.relationships.relationshipEmojis;
|
||||||
|
|
||||||
|
while (existingRelationships[relationshipName]) {
|
||||||
|
counter++;
|
||||||
|
relationshipName = `${baseName} ${counter}`;
|
||||||
|
}
|
||||||
|
|
||||||
// Add to new structure
|
// Add to new structure
|
||||||
extensionSettings.trackerConfig.presentCharacters.relationships.relationshipEmojis['New Relationship'] = '😊';
|
extensionSettings.trackerConfig.presentCharacters.relationships.relationshipEmojis[relationshipName] = '😊';
|
||||||
|
|
||||||
// Also update legacy fields for backward compatibility
|
// Also update legacy fields for backward compatibility
|
||||||
if (!extensionSettings.trackerConfig.presentCharacters.relationshipEmojis) {
|
if (!extensionSettings.trackerConfig.presentCharacters.relationshipEmojis) {
|
||||||
extensionSettings.trackerConfig.presentCharacters.relationshipEmojis = {};
|
extensionSettings.trackerConfig.presentCharacters.relationshipEmojis = {};
|
||||||
}
|
}
|
||||||
extensionSettings.trackerConfig.presentCharacters.relationshipEmojis['New Relationship'] = '😊';
|
extensionSettings.trackerConfig.presentCharacters.relationshipEmojis[relationshipName] = '😊';
|
||||||
|
|
||||||
// Sync relationshipFields
|
// Sync relationshipFields
|
||||||
const emojis = extensionSettings.trackerConfig.presentCharacters.relationships.relationshipEmojis;
|
const emojis = extensionSettings.trackerConfig.presentCharacters.relationships.relationshipEmojis;
|
||||||
|
|||||||
@@ -601,6 +601,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
position: relative; /* For absolute positioning of lock icon on mobile */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hide the stats header - we'll integrate portrait/inventory into stats content */
|
/* Hide the stats header - we'll integrate portrait/inventory into stats content */
|
||||||
@@ -4231,6 +4232,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
background: var(--rpg-accent);
|
background: var(--rpg-accent);
|
||||||
border: 1px solid var(--rpg-border);
|
border: 1px solid var(--rpg-border);
|
||||||
border-radius: 0.375em;
|
border-radius: 0.375em;
|
||||||
|
min-width: 0; /* Allow grid items to shrink below content size */
|
||||||
}
|
}
|
||||||
|
|
||||||
.rpg-field-controls {
|
.rpg-field-controls {
|
||||||
@@ -4269,6 +4271,13 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
border-radius: 0.25em;
|
border-radius: 0.25em;
|
||||||
color: var(--rpg-text);
|
color: var(--rpg-text);
|
||||||
font-size: 0.95em;
|
font-size: 0.95em;
|
||||||
|
word-wrap: break-word;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
min-width: 0; /* Allow input to shrink */
|
||||||
|
width: 100%; /* Fill available grid space */
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rpg-field-remove,
|
.rpg-field-remove,
|
||||||
@@ -4305,15 +4314,28 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
|
|
||||||
/* Footer buttons */
|
/* Footer buttons */
|
||||||
.rpg-settings-popup-footer {
|
.rpg-settings-popup-footer {
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
border-top: 2px solid var(--rpg-border);
|
border-top: 2px solid var(--rpg-border);
|
||||||
gap: 1em;
|
|
||||||
background: var(--rpg-accent);
|
background: var(--rpg-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rpg-editor-footer-buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-editor-footer-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5em;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-editor-footer-row:last-child button {
|
||||||
|
flex: 1;
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
.rpg-footer-left {
|
.rpg-footer-left {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 0.5em;
|
gap: 0.5em;
|
||||||
@@ -5116,15 +5138,15 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
/* Mobile panel - slide from right like desktop */
|
/* Mobile panel - slide from right like desktop */
|
||||||
.rpg-panel {
|
.rpg-panel {
|
||||||
position: fixed !important;
|
position: fixed !important;
|
||||||
top: var(--topBarBlockSize) !important;
|
top: 0 !important;
|
||||||
right: 0 !important;
|
right: 0 !important;
|
||||||
bottom: 0 !important;
|
bottom: 0 !important;
|
||||||
left: auto !important;
|
left: auto !important;
|
||||||
|
|
||||||
/* Mobile panel sizing */
|
/* Mobile panel sizing */
|
||||||
width: 85dvw !important;
|
width: 85vw !important;
|
||||||
max-width: 400px !important;
|
max-width: 400px !important;
|
||||||
height: calc(100dvh - var(--topBarBlockSize)) !important;
|
height: 100vh !important;
|
||||||
|
|
||||||
/* Hidden by default - completely removed from layout */
|
/* Hidden by default - completely removed from layout */
|
||||||
display: none !important;
|
display: none !important;
|
||||||
@@ -5154,14 +5176,14 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
/* Show panel when opened with slide-in animation */
|
/* Show panel when opened with slide-in animation */
|
||||||
.rpg-panel.rpg-mobile-open {
|
.rpg-panel.rpg-mobile-open {
|
||||||
display: block !important;
|
display: block !important;
|
||||||
z-index: 50;
|
z-index: 9999;
|
||||||
animation: rpgSlideInFromRight 0.3s ease-in-out;
|
animation: rpgSlideInFromRight 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Closing animation - slide out to right */
|
/* Closing animation - slide out to right */
|
||||||
.rpg-panel.rpg-mobile-closing {
|
.rpg-panel.rpg-mobile-closing {
|
||||||
display: block !important;
|
display: block !important;
|
||||||
z-index: 50;
|
z-index: 9999;
|
||||||
animation: rpgSlideOutToRight 0.3s ease-in-out;
|
animation: rpgSlideOutToRight 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+29
-23
@@ -492,7 +492,7 @@
|
|||||||
data-i18n-key="template.settingsModal.advanced.contextMessages">Context Messages:</label>
|
data-i18n-key="template.settingsModal.advanced.contextMessages">Context Messages:</label>
|
||||||
<input type="number" id="rpg-update-depth" min="1" max="20" value="4" class="rpg-input" />
|
<input type="number" id="rpg-update-depth" min="1" max="20" value="4" class="rpg-input" />
|
||||||
<small data-i18n-key="template.settingsModal.advanced.contextMessagesNote">Number of recent messages
|
<small data-i18n-key="template.settingsModal.advanced.contextMessagesNote">Number of recent messages
|
||||||
to include (Separate mode only)</small>
|
to include (Separate/External mode)</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -694,27 +694,26 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="rpg-settings-popup-footer">
|
<footer class="rpg-settings-popup-footer">
|
||||||
<div class="rpg-footer-left">
|
<div class="rpg-editor-footer-buttons">
|
||||||
<button id="rpg-editor-reset" class="rpg-btn-secondary" type="button">
|
<div class="rpg-editor-footer-row">
|
||||||
<i class="fa-solid fa-rotate-left"></i> <span
|
<button id="rpg-editor-reset" class="rpg-btn-secondary" type="button">
|
||||||
data-i18n-key="template.trackerEditorModal.buttons.reset">Reset to Defaults</span>
|
<i class="fa-solid fa-rotate-left"></i> <span
|
||||||
</button>
|
data-i18n-key="template.trackerEditorModal.buttons.reset">Reset</span>
|
||||||
<button id="rpg-editor-export" class="rpg-btn-secondary" type="button">
|
</button>
|
||||||
<i class="fa-solid fa-file-export"></i> <span
|
<button id="rpg-editor-export" class="rpg-btn-secondary" type="button">
|
||||||
data-i18n-key="template.trackerEditorModal.buttons.export">Export Preset</span>
|
<i class="fa-solid fa-file-export"></i> <span
|
||||||
</button>
|
data-i18n-key="template.trackerEditorModal.buttons.export">Export</span>
|
||||||
<button id="rpg-editor-import" class="rpg-btn-secondary" type="button">
|
</button>
|
||||||
<i class="fa-solid fa-file-import"></i> <span
|
<button id="rpg-editor-import" class="rpg-btn-secondary" type="button">
|
||||||
data-i18n-key="template.trackerEditorModal.buttons.import">Import Preset</span>
|
<i class="fa-solid fa-file-import"></i> <span
|
||||||
</button>
|
data-i18n-key="template.trackerEditorModal.buttons.import">Import</span>
|
||||||
</div>
|
</button>
|
||||||
<div class="rpg-footer-right">
|
</div>
|
||||||
<button id="rpg-editor-cancel" class="rpg-btn-secondary" type="button"
|
<div class="rpg-editor-footer-row">
|
||||||
data-i18n-key="template.trackerEditorModal.buttons.cancel">Cancel</button>
|
<button id="rpg-editor-save" class="rpg-btn-primary" type="button">
|
||||||
<button id="rpg-editor-save" class="rpg-btn-primary" type="button">
|
<i class="fa-solid fa-save"></i> <span data-i18n-key="template.trackerEditorModal.buttons.save">Save & Apply</span>
|
||||||
<i class="fa-solid fa-save"></i> <span data-i18n-key="template.trackerEditorModal.buttons.save">Save
|
</button>
|
||||||
& Apply</span>
|
</div>
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
@@ -899,7 +898,7 @@
|
|||||||
<header class="rpg-settings-popup-header">
|
<header class="rpg-settings-popup-header">
|
||||||
<h3 id="rpg-welcome-title">
|
<h3 id="rpg-welcome-title">
|
||||||
<i class="fa-solid fa-stars"></i>
|
<i class="fa-solid fa-stars"></i>
|
||||||
Welcome to RPG Companion v.3.0.0!
|
Welcome to RPG Companion v.3.2.0!
|
||||||
</h3>
|
</h3>
|
||||||
<button id="rpg-welcome-close" class="rpg-popup-close" type="button"
|
<button id="rpg-welcome-close" class="rpg-popup-close" type="button"
|
||||||
aria-label="Close Welcome">
|
aria-label="Close Welcome">
|
||||||
@@ -932,6 +931,13 @@
|
|||||||
<li>Spotify Music widget is more visible now, plus it works in the mobile view.</li>
|
<li>Spotify Music widget is more visible now, plus it works in the mobile view.</li>
|
||||||
<li>Auto-update after messages option is now available for External API generation mode.</li>
|
<li>Auto-update after messages option is now available for External API generation mode.</li>
|
||||||
<li>Fixed the display of the thoughts window and its mobile display.</li>
|
<li>Fixed the display of the thoughts window and its mobile display.</li>
|
||||||
|
<li>Mobile UI fixes (panel viewport and z-index issues).</li>
|
||||||
|
<li>Fixed the regex issue in Together mode (JSON blocks now hidden from display).</li>
|
||||||
|
<li>Fixed parsing error appearing when loading or switching chats.</li>
|
||||||
|
<li>Fixed adding new relationships in Edit Trackers (unique naming).</li>
|
||||||
|
<li>Added migration support for importing older tracker presets.</li>
|
||||||
|
<li>Lifted attributes cap from 100 to 999.</li>
|
||||||
|
<li>Fixed lock icon positioning on mobile devices.</li>
|
||||||
<li>Fixed smaller bugs.</li>
|
<li>Fixed smaller bugs.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user