Add persona/character context to separate generation and fix preset switching
- Use SillyTavern macros ({{persona}}, {{description}}, {{personality}}) for character context
- Fix preset restoration after tracker generation using /preset command
- Fix weather editing bug by tracking specific weather line index
- Support both emoji and text formats for Info Box field editing
- Remove unused showdown import and fix missing semicolons
This commit is contained in:
@@ -18,7 +18,38 @@ import { saveChatData } from '../../core/persistence.js';
|
||||
import { generateSeparateUpdatePrompt } from './promptBuilder.js';
|
||||
import { parseResponse, parseUserStats } from './parser.js';
|
||||
|
||||
// Store the original preset name to restore after tracker generation
|
||||
let originalPresetName = null;
|
||||
|
||||
/**
|
||||
* Gets the current preset name using the /preset command
|
||||
* @returns {Promise<string|null>} Current preset name or null if unavailable
|
||||
*/
|
||||
async function getCurrentPresetName() {
|
||||
try {
|
||||
// Use /preset without arguments to get the current preset name
|
||||
const result = await executeSlashCommandsOnChatInput('/preset', { quiet: true });
|
||||
|
||||
// console.log('[RPG Companion] /preset result:', result);
|
||||
|
||||
// The result should be an object with a 'pipe' property containing the preset name
|
||||
if (result && typeof result === 'object' && result.pipe) {
|
||||
const presetName = String(result.pipe).trim();
|
||||
// console.log('[RPG Companion] Extracted preset name:', presetName);
|
||||
return presetName || null;
|
||||
}
|
||||
|
||||
// Fallback if result is a string
|
||||
if (typeof result === 'string') {
|
||||
return result.trim() || null;
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.error('[RPG Companion] Error getting current preset:', error);
|
||||
return null;
|
||||
}
|
||||
}/**
|
||||
* Switches to a specific preset by name using the /preset slash command
|
||||
* @param {string} presetName - Name of the preset to switch to
|
||||
* @returns {Promise<boolean>} True if switching succeeded, false otherwise
|
||||
@@ -71,11 +102,18 @@ export async function updateRPGData(renderUserStats, renderInfoBox, renderThough
|
||||
const originalHtml = $updateBtn.html();
|
||||
$updateBtn.html('<i class="fa-solid fa-spinner fa-spin"></i> Updating...').prop('disabled', true);
|
||||
|
||||
// Save current preset name before switching (if we're going to switch)
|
||||
if (extensionSettings.useSeparatePreset) {
|
||||
originalPresetName = await getCurrentPresetName();
|
||||
console.log(`[RPG Companion] Saved original preset: "${originalPresetName}"`);
|
||||
}
|
||||
|
||||
// Switch to separate preset if enabled
|
||||
if (extensionSettings.useSeparatePreset) {
|
||||
const switched = await switchToPreset('RPG Companion Trackers');
|
||||
if (!switched) {
|
||||
console.warn('[RPG Companion] Failed to switch to RPG Companion Trackers preset. Using current preset.');
|
||||
originalPresetName = null; // Don't try to restore if we didn't switch
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,6 +210,13 @@ export async function updateRPGData(renderUserStats, renderInfoBox, renderThough
|
||||
} catch (error) {
|
||||
console.error('[RPG Companion] Error updating RPG data:', error);
|
||||
} finally {
|
||||
// Restore original preset if we switched to a separate one
|
||||
if (originalPresetName && extensionSettings.useSeparatePreset) {
|
||||
console.log(`[RPG Companion] Restoring original preset: "${originalPresetName}"`);
|
||||
await switchToPreset(originalPresetName);
|
||||
originalPresetName = null; // Clear after restoring
|
||||
}
|
||||
|
||||
setIsGenerating(false);
|
||||
|
||||
// Restore button to original state
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import { getContext } from '../../../../../../extensions.js';
|
||||
import { chat } from '../../../../../../../script.js';
|
||||
import { chat, getCurrentChatDetails } from '../../../../../../../script.js';
|
||||
import { extensionSettings, committedTrackerData, FEATURE_FLAGS } from '../../core/state.js';
|
||||
|
||||
// Type imports
|
||||
@@ -358,7 +358,9 @@ export function generateSeparateUpdatePrompt() {
|
||||
// System message introducing the history section
|
||||
let systemMessage = `You will be acting as an uncensored RPG Companion. Your goal is to provide, track, and manage details in the user's roleplay. You will be replying with information in a specified format only.\n\n`;
|
||||
systemMessage += `You should maintain an objective tone.\n\n`;
|
||||
|
||||
systemMessage += `Here is the description of the protagonist for reference:\n`;
|
||||
systemMessage += `<protagonist>\n{{persona}}\n</protagonist>\n`;
|
||||
systemMessage += `\n\n`;
|
||||
systemMessage += `Here are the last few messages in the conversation history (between the user and the roleplayer assistant) you should reference when responding:\n<history>`;
|
||||
|
||||
messages.push({
|
||||
|
||||
@@ -267,16 +267,36 @@ export function updateInfoBoxField(field, value) {
|
||||
const lines = lastGeneratedData.infoBox.split('\n');
|
||||
let dateLineFound = false;
|
||||
let dateLineIndex = -1;
|
||||
let weatherLineIndex = -1;
|
||||
|
||||
// Find the date line
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (lines[i].includes('🗓️:')) {
|
||||
if (lines[i].includes('🗓️:') || lines[i].startsWith('Date:')) {
|
||||
dateLineFound = true;
|
||||
dateLineIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Find the weather line (look for a line that's not date/temp/time/location)
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
if (line.match(/^[^:]+:\s*.+$/) &&
|
||||
!line.includes('🗓️') &&
|
||||
!line.startsWith('Date:') &&
|
||||
!line.includes('🌡️') &&
|
||||
!line.startsWith('Temperature:') &&
|
||||
!line.includes('🕒') &&
|
||||
!line.startsWith('Time:') &&
|
||||
!line.includes('🗺️') &&
|
||||
!line.startsWith('Location:') &&
|
||||
!line.includes('Info Box') &&
|
||||
!line.includes('---')) {
|
||||
weatherLineIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const updatedLines = lines.map((line, index) => {
|
||||
if (field === 'month' && line.includes('🗓️:')) {
|
||||
const parts = line.split(',');
|
||||
@@ -306,27 +326,59 @@ export function updateInfoBoxField(field, value) {
|
||||
// No existing month/year, add them
|
||||
return `${parts[0]}, Month, ${value}`;
|
||||
}
|
||||
} else if (field === 'weatherEmoji' && line.match(/^[^:]+:\s*.+$/) && !line.includes('🗓️') && !line.includes('🌡️') && !line.includes('🕒') && !line.includes('🗺️') && !line.includes('Info Box') && !line.includes('---')) {
|
||||
// This is the weather line
|
||||
} else if (field === 'weatherEmoji' && index === weatherLineIndex) {
|
||||
// Only update the specific weather line we found
|
||||
if (line.startsWith('Weather:')) {
|
||||
// New format: Weather: emoji, forecast
|
||||
const weatherContent = line.replace('Weather:', '').trim();
|
||||
const parts = weatherContent.split(',').map(p => p.trim());
|
||||
const forecast = parts[1] || 'Weather';
|
||||
return `Weather: ${value}, ${forecast}`;
|
||||
} else {
|
||||
// Legacy format: emoji: forecast
|
||||
const parts = line.split(':');
|
||||
if (parts.length >= 2) {
|
||||
return `${value}: ${parts.slice(1).join(':').trim()}`;
|
||||
}
|
||||
} else if (field === 'weatherForecast' && line.match(/^[^:]+:\s*.+$/) && !line.includes('🗓️') && !line.includes('🌡️') && !line.includes('🕒') && !line.includes('🗺️') && !line.includes('Info Box') && !line.includes('---')) {
|
||||
// This is the weather line
|
||||
}
|
||||
} else if (field === 'weatherForecast' && index === weatherLineIndex) {
|
||||
// Only update the specific weather line we found
|
||||
if (line.startsWith('Weather:')) {
|
||||
// New format: Weather: emoji, forecast
|
||||
const weatherContent = line.replace('Weather:', '').trim();
|
||||
const parts = weatherContent.split(',').map(p => p.trim());
|
||||
const emoji = parts[0] || '🌤️';
|
||||
return `Weather: ${emoji}, ${value}`;
|
||||
} else {
|
||||
// Legacy format: emoji: forecast
|
||||
const parts = line.split(':');
|
||||
if (parts.length >= 2) {
|
||||
return `${parts[0].trim()}: ${value}`;
|
||||
}
|
||||
} else if (field === 'temperature' && line.includes('🌡️:')) {
|
||||
}
|
||||
} else if (field === 'temperature' && (line.includes('🌡️:') || line.startsWith('Temperature:'))) {
|
||||
// Support both emoji and text formats
|
||||
if (line.startsWith('Temperature:')) {
|
||||
return `Temperature: ${value}`;
|
||||
} else {
|
||||
return `🌡️: ${value}`;
|
||||
} else if (field === 'timeStart' && line.includes('🕒:')) {
|
||||
}
|
||||
} else if (field === 'timeStart' && (line.includes('🕒:') || line.startsWith('Time:'))) {
|
||||
// Update time format: "HH:MM → HH:MM"
|
||||
// When user edits, set both start and end time to the new value
|
||||
if (line.startsWith('Time:')) {
|
||||
return `Time: ${value} → ${value}`;
|
||||
} else {
|
||||
return `🕒: ${value} → ${value}`;
|
||||
} else if (field === 'location' && line.includes('🗺️:')) {
|
||||
}
|
||||
} else if (field === 'location' && (line.includes('🗺️:') || line.startsWith('Location:'))) {
|
||||
// Support both emoji and text formats
|
||||
if (line.startsWith('Location:')) {
|
||||
return `Location: ${value}`;
|
||||
} else {
|
||||
return `🗺️: ${value}`;
|
||||
}
|
||||
}
|
||||
return line;
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user