Fix: Strip thinking tags from parser and persist tracker data on page refresh

- Added removal of <think> and <thinking> tags from AI responses before parsing
- Fixed Info Box display to use committedTrackerData as fallback after page refresh
- Fixed Present Characters display to use committedTrackerData as fallback after page refresh
- Fixed 4-part character format handling in updateCharacterField to preserve thoughts
- Ensures Recent Events and all tracker data persist correctly across page reloads
This commit is contained in:
Spicy_Marinara
2025-10-28 18:07:15 +01:00
parent a063ae780b
commit 13019c65ee
3 changed files with 57 additions and 19 deletions
+38 -7
View File
@@ -46,6 +46,31 @@ function separateEmojiFromText(str) {
return { emoji: '', text: str };
}
/**
* Helper to strip enclosing brackets from text
* Removes [], {}, and () from the entire text if it's wrapped
* @param {string} text - Text that may be wrapped in brackets
* @returns {string} Text with brackets removed
*/
function stripBrackets(text) {
if (!text) return text;
// Remove leading and trailing whitespace first
text = text.trim();
// Check if the entire text is wrapped in brackets and remove them
// This handles cases where models wrap entire sections in brackets
while (
(text.startsWith('[') && text.endsWith(']')) ||
(text.startsWith('{') && text.endsWith('}')) ||
(text.startsWith('(') && text.endsWith(')'))
) {
text = text.substring(1, text.length - 1).trim();
}
return text;
}
/**
* Helper to log to both console and debug logs array
*/
@@ -76,9 +101,15 @@ export function parseResponse(responseText) {
debugLog('[RPG Parser] Response length:', responseText.length + ' chars');
debugLog('[RPG Parser] First 500 chars:', responseText.substring(0, 500));
// Remove content inside thinking tags first (model's internal reasoning)
// This prevents parsing code blocks from the model's thinking process
let cleanedResponse = responseText.replace(/<think>[\s\S]*?<\/think>/gi, '');
cleanedResponse = cleanedResponse.replace(/<thinking>[\s\S]*?<\/thinking>/gi, '');
debugLog('[RPG Parser] Removed thinking tags, new length:', cleanedResponse.length + ' chars');
// Extract code blocks
const codeBlockRegex = /```([^`]+)```/g;
const matches = [...responseText.matchAll(codeBlockRegex)];
const matches = [...cleanedResponse.matchAll(codeBlockRegex)];
debugLog('[RPG Parser] Found', matches.length + ' code blocks');
@@ -102,21 +133,21 @@ export function parseResponse(responseText) {
// Extract User Stats section
const statsMatch = content.match(/(User )?Stats\s*\n\s*---[\s\S]*?(?=\n\s*\n\s*(Info Box|Present Characters)|$)/i);
if (statsMatch && !result.userStats) {
result.userStats = statsMatch[0].trim();
result.userStats = stripBrackets(statsMatch[0].trim());
debugLog('[RPG Parser] ✓ Extracted Stats from combined block');
}
// Extract Info Box section
const infoBoxMatch = content.match(/Info Box\s*\n\s*---[\s\S]*?(?=\n\s*\n\s*Present Characters|$)/i);
if (infoBoxMatch && !result.infoBox) {
result.infoBox = infoBoxMatch[0].trim();
result.infoBox = stripBrackets(infoBoxMatch[0].trim());
debugLog('[RPG Parser] ✓ Extracted Info Box from combined block');
}
// Extract Present Characters section
const charactersMatch = content.match(/Present Characters\s*\n\s*---[\s\S]*$/i);
if (charactersMatch && !result.characterThoughts) {
result.characterThoughts = charactersMatch[0].trim();
result.characterThoughts = stripBrackets(charactersMatch[0].trim());
debugLog('[RPG Parser] ✓ Extracted Present Characters from combined block');
}
} else {
@@ -146,13 +177,13 @@ export function parseResponse(responseText) {
(content.includes(" | ") && (content.includes("Thoughts") || content.includes("💭")));
if (isStats && !result.userStats) {
result.userStats = content;
result.userStats = stripBrackets(content);
debugLog('[RPG Parser] ✓ Matched: Stats section');
} else if (isInfoBox && !result.infoBox) {
result.infoBox = content;
result.infoBox = stripBrackets(content);
debugLog('[RPG Parser] ✓ Matched: Info Box section');
} else if (isCharacters && !result.characterThoughts) {
result.characterThoughts = content;
result.characterThoughts = stripBrackets(content);
debugLog('[RPG Parser] ✓ Matched: Present Characters section');
debugLog('[RPG Parser] Full content:', content);
} else {
+6 -3
View File
@@ -64,8 +64,11 @@ export function renderInfoBox() {
$infoBoxContainer.addClass('rpg-content-updating');
}
// Use committedTrackerData as fallback if lastGeneratedData is empty (e.g., after page refresh)
const infoBoxData = lastGeneratedData.infoBox || committedTrackerData.infoBox;
// If no data yet, show placeholder
if (!lastGeneratedData.infoBox) {
if (!infoBoxData) {
const placeholderHtml = `
<div class="rpg-dashboard rpg-dashboard-row-1">
<div class="rpg-dashboard-widget rpg-placeholder-widget">
@@ -81,10 +84,10 @@ export function renderInfoBox() {
return;
}
// console.log('[RPG Companion] renderInfoBox called with data:', lastGeneratedData.infoBox);
// console.log('[RPG Companion] renderInfoBox called with data:', infoBoxData);
// Parse the info box data
const lines = lastGeneratedData.infoBox.split('\n');
const lines = infoBoxData.split('\n');
// console.log('[RPG Companion] Info Box split into lines:', lines);
const data = {
date: '',
+13 -9
View File
@@ -76,15 +76,13 @@ export function renderThoughts() {
$thoughtsContainer.addClass('rpg-content-updating');
}
// Initialize if no data yet
if (!lastGeneratedData.characterThoughts) {
lastGeneratedData.characterThoughts = '';
}
// Use committedTrackerData as fallback if lastGeneratedData is empty (e.g., after page refresh)
const characterThoughtsData = lastGeneratedData.characterThoughts || committedTrackerData.characterThoughts || '';
debugLog('[RPG Thoughts] Raw characterThoughts data:', lastGeneratedData.characterThoughts);
debugLog('[RPG Thoughts] Data length:', lastGeneratedData.characterThoughts.length + ' chars');
debugLog('[RPG Thoughts] Raw characterThoughts data:', characterThoughtsData);
debugLog('[RPG Thoughts] Data length:', characterThoughtsData.length + ' chars');
const lines = lastGeneratedData.characterThoughts.split('\n');
const lines = characterThoughtsData.split('\n');
const presentCharacters = [];
debugLog('[RPG Thoughts] Split into lines count:', lines.length);
@@ -378,8 +376,14 @@ export function updateCharacterField(characterName, field, value) {
if (emojiMatch) {
let emoji = emojiMatch[1].trim();
let info = emojiMatch[2].trim();
let relationship = parts[1];
let thoughts = parts[2] || '';
let relationship = parts[1] ? parts[1].trim() : '';
let thoughts = parts[2] ? parts[2].trim() : '';
// Handle 4-part format (with demeanor)
if (parts.length >= 4) {
relationship = parts[2] ? parts[2].trim() : '';
thoughts = parts[3] ? parts[3].trim() : '';
}
const infoParts = info.split(',').map(p => p.trim());
let name = infoParts[0];