diff --git a/src/systems/generation/promptBuilder.js b/src/systems/generation/promptBuilder.js index fa98726..92a8f5f 100644 --- a/src/systems/generation/promptBuilder.js +++ b/src/systems/generation/promptBuilder.js @@ -182,7 +182,7 @@ function buildAttributesString() { /** * Generates JSON-based tracker instructions. * Creates a prompt asking the LLM to output structured JSON data. - * + * * @param {boolean} includeHtmlPrompt - Whether to include the HTML prompt * @param {boolean} includeContinuation - Whether to include continuation instruction * @param {boolean} includeAttributes - Whether to include RPG attributes @@ -224,7 +224,7 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ const enabledStats = trackerConfig?.userStats?.customStats?.filter(s => s?.enabled && s?.name) || []; if (enabledStats.length > 0) { let statsJson = ' "stats": {\n'; - statsJson += enabledStats.map(s => ` "${s.name}": X`).join(',\n'); + statsJson += enabledStats.map(s => ` "${s.name}": 75`).join(',\n'); statsJson += '\n }'; sections.push(statsJson); } @@ -235,7 +235,7 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ let statusJson = ' "status": {\n'; const statusParts = []; if (statusConfig.showMoodEmoji) { - statusParts.push(' "mood": "[Mood Emoji]"'); + statusParts.push(' "mood": "😊"'); } const customFields = statusConfig.customFields || []; if (customFields.length > 0) { @@ -250,7 +250,7 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ // Skills section const skillsSectionEnabled = trackerConfig?.userStats?.skillsSection?.enabled || false; if (skillsSectionEnabled && !extensionSettings.showSkills) { - sections.push(` "skills": "[Skills]"`); + sections.push(` "skills": "Skill1, Skill2, Skill3"`); } } @@ -258,7 +258,7 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ const showRPGAttributes = trackerConfig?.userStats?.showRPGAttributes; const alwaysSendAttributes = trackerConfig?.userStats?.alwaysSendAttributes; const shouldSendAttributes = alwaysSendAttributes || extensionSettings.lastDiceRoll; - + if (showRPGAttributes && shouldSendAttributes) { const rpgAttributes = trackerConfig?.userStats?.rpgAttributes || [ { id: 'str', name: 'STR', description: '', enabled: true }, @@ -269,7 +269,7 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ { id: 'cha', name: 'CHA', description: '', enabled: true } ]; const enabledAttributes = rpgAttributes.filter(attr => attr && attr.enabled && attr.name && attr.id); - + if (enabledAttributes.length > 0) { let attrsJson = ' "attributes": {\n'; const attrParts = enabledAttributes.map(attr => { @@ -279,7 +279,7 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ attrsJson += attrParts.join(',\n'); attrsJson += '\n }'; sections.push(attrsJson); - + // Add level const currentLevel = extensionSettings.level ?? 1; sections.push(` "level": ${currentLevel}`); @@ -290,16 +290,16 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ if (showInfoBox) { const widgets = trackerConfig?.infoBox?.widgets || {}; const infoParts = []; - if (widgets.date?.enabled) infoParts.push(' "date": "[Day, Month, Year]"'); - if (widgets.time?.enabled) infoParts.push(' "time": "[Time Start → Time End]"'); - if (widgets.weather?.enabled) infoParts.push(' "weather": "[Weather Emoji, Weather]"'); + if (widgets.date?.enabled) infoParts.push(' "date": "Monday, March 15, 1242"'); + if (widgets.time?.enabled) infoParts.push(' "time": "14:00 → 15:30"'); + if (widgets.weather?.enabled) infoParts.push(' "weather": "☀️ Sunny"'); if (widgets.temperature?.enabled) { const unit = widgets.temperature.unit === 'F' ? '°F' : '°C'; - infoParts.push(` "temperature": "X${unit}"`); + infoParts.push(` "temperature": "22${unit}"`); } - if (widgets.location?.enabled) infoParts.push(' "location": "[Location]"'); - if (widgets.recentEvents?.enabled) infoParts.push(' "recentEvents": "[Events]"'); - + if (widgets.location?.enabled) infoParts.push(' "location": "Forest Clearing"'); + if (widgets.recentEvents?.enabled) infoParts.push(' "recentEvents": ["Event 1", "Event 2"]'); + if (infoParts.length > 0) { sections.push(' "infoBox": {\n' + infoParts.join(',\n') + '\n }'); } @@ -308,32 +308,32 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ // Characters section if (showCharacters) { const charConfig = trackerConfig?.presentCharacters || {}; - let charExample = ' {\n "name": "Character Name",\n "emoji": "[Character Emoji]"'; - + let charExample = ' {\n "name": "Character Name",\n "emoji": "🧑"'; + if (charConfig.relationshipFields?.length > 0) { // Show allowed relationship values as explanation const allowedRelationships = charConfig.relationshipFields.join(' | '); - charExample += `,\n "relationship": "[${allowedRelationships}]"`; + charExample += `,\n "relationship": "(${allowedRelationships})"`; } - + const enabledFields = charConfig.customFields?.filter(f => f.enabled) || []; if (enabledFields.length > 0) { const fieldsJson = enabledFields.map(f => ` "${f.name}": "[${f.description || f.name}]"`).join(',\n'); charExample += `,\n "fields": {\n${fieldsJson}\n }`; } - + // Character stats (Health, Arousal, etc.) const charStatsConfig = charConfig.characterStats; const enabledCharStats = charStatsConfig?.enabled && charStatsConfig?.customStats?.filter(s => s?.enabled && s?.name) || []; if (enabledCharStats.length > 0) { - const statsJson = enabledCharStats.map(s => ` "${s.name}": X`).join(',\n'); + const statsJson = enabledCharStats.map(s => ` "${s.name}": 75`).join(',\n'); charExample += `,\n "stats": {\n${statsJson}\n }`; } - + if (charConfig.thoughts?.enabled) { charExample += ',\n "thoughts": "Character\'s inner thoughts in first person..."'; } - + charExample += '\n }'; sections.push(' "characters": [\n' + charExample + '\n ]'); } @@ -341,25 +341,25 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ // Inventory section if (showInventory) { let invSection = ' "inventory": {\n'; - + if (extensionSettings.useSimplifiedInventory) { // Simplified: single list - let itemExample = '{ "name": "Item Name", "description": "[What It Is]" }'; + let itemExample = '{ "name": "Item Name", "description": "What it is" }'; if (enableItemSkillLinks) { - itemExample = '{ "name": "Iron Sword", "description": "[What It Is]", "grantsSkill": "[Skill]" }'; + itemExample = '{ "name": "Iron Sword", "description": "A sturdy blade", "grantsSkill": "Sword Fighting" }'; } invSection += ` "items": [${itemExample}]\n`; } else { // Full categorized inventory let itemExample = '{ "name": "Item", "description": "Description" }'; if (enableItemSkillLinks) { - itemExample = '{ "name": "Iron Sword", "description": "[What It Is]", "grantsSkill": "[Skill]" }'; + itemExample = '{ "name": "Iron Sword", "description": "A sturdy blade", "grantsSkill": "Sword Fighting" }'; } invSection += ` "onPerson": [${itemExample}],\n`; - invSection += ' "stored": { "Location Name": [{ "name": "Stored Item", "description": "[What It Is]" }] },\n'; - invSection += ' "assets": [{ "name": "[Property/Vehicle]", "description": "[What It Is]" }]\n'; + invSection += ' "stored": { "Location Name": [{ "name": "Stored Item", "description": "Description" }] },\n'; + invSection += ' "assets": [{ "name": "Property/Vehicle", "description": "Description" }]\n'; } - + invSection += ' }'; sections.push(invSection); } @@ -369,14 +369,14 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ const skillCategories = trackerConfig?.userStats?.skillsSection?.customFields || []; // Migration function handles string array → object array conversion on load const enabledCategories = skillCategories.filter(cat => cat.enabled !== false); - + if (enabledCategories.length > 0) { let skillsSection = ' "skills": {\n'; const categoryExamples = enabledCategories.map(cat => { const catName = cat.name; - let skillExample = '{ "name": "Ability Name", "description": "[What This Ability Does]" }'; + let skillExample = '{ "name": "Ability Name", "description": "What this ability does" }'; if (enableItemSkillLinks) { - skillExample = '{ "name": "Ability", "description": "[Description]", "grantedBy": "[Item Name]" }'; + skillExample = '{ "name": "Ability", "description": "Description", "grantedBy": "Item Name" }'; } return ` "${catName}": [${skillExample}]`; }); @@ -389,8 +389,8 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ // Quests section if (showQuests) { let questsSection = ' "quests": {\n'; - questsSection += ' "main": { "name": "Main Quest Title", "description": "[Primary objective]" },\n'; - questsSection += ' "optional": [{ "name": "Side Quest", "description": "[Optional objective]" }]\n'; + questsSection += ' "main": { "name": "Main Quest Title", "description": "Primary objective" },\n'; + questsSection += ' "optional": [{ "name": "Side Quest", "description": "Optional objective" }]\n'; questsSection += ' }'; sections.push(questsSection); } @@ -419,7 +419,7 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ instructions += '- Your list of characters must never include {{user}}\n'; instructions += '- Empty arrays [] for sections with no items\n'; instructions += '- null for main quest if none active\n'; - + // Add stat descriptions if any have descriptions if (showStats) { const customStats = trackerConfig?.userStats?.customStats || []; @@ -431,16 +431,16 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ }); } } - + if (showSkills) { const skillsLabel = trackerConfig?.userStats?.skillsSection?.label || 'Skills'; if (skillsLabel !== 'Skills') { instructions += `- The "skills" section represents "${skillsLabel}" in this context\n`; } - + // Add skill category descriptions if any have descriptions const skillCategories = trackerConfig?.userStats?.skillsSection?.customFields || []; - const categoriesWithDesc = skillCategories.filter(cat => + const categoriesWithDesc = skillCategories.filter(cat => typeof cat === 'object' && cat.description && cat.enabled !== false ); if (categoriesWithDesc.length > 0) { @@ -450,7 +450,7 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ }); } } - + if (enableItemSkillLinks) { instructions += '- Items can grant skills: add {"grantsSkill": "Skill Name"} to the item object\n'; instructions += '- When a skill comes from an item, add {"grantedBy": "Item Name"} to that skill object\n'; @@ -458,7 +458,7 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ instructions += '- If an item is removed/lost, also remove any skill it granted\n'; } } - + instructions += '\n'; // Continuation instruction @@ -474,7 +474,7 @@ export function generateJSONTrackerInstructions(includeHtmlPrompt = true, includ if (shouldSendAttributes) { const attributesString = buildAttributesString(); instructions += `${userName}'s attributes: ${attributesString}\n`; - + // Add attribute descriptions if any have descriptions const rpgAttributes = trackerConfig?.userStats?.rpgAttributes || []; const attrsWithDesc = rpgAttributes.filter(a => a?.enabled && a?.description); @@ -515,7 +515,7 @@ export function generateContextualSummary() { const currentState = {}; const trackerConfig = extensionSettings.trackerConfig; const descriptions = {}; - + // Stats if (extensionSettings.showUserStats) { const customStats = trackerConfig?.userStats?.customStats?.filter(s => s?.enabled) || []; @@ -529,7 +529,7 @@ export function generateContextualSummary() { } } } - + // Status const statusConfig = trackerConfig?.userStats?.statusSection; if (statusConfig?.enabled) { @@ -549,12 +549,12 @@ export function generateContextualSummary() { currentState.skills = extensionSettings.userStats?.skills || 'None'; } } - + // InfoBox if (extensionSettings.showInfoBox && extensionSettings.infoBoxData) { currentState.infoBox = extensionSettings.infoBoxData; } - + // Characters - format to match schema if (extensionSettings.showCharacterThoughts && extensionSettings.charactersData?.length > 0) { // Ensure characters match the expected schema format @@ -567,7 +567,7 @@ export function generateContextualSummary() { if (char.thoughts) formatted.thoughts = char.thoughts; return formatted; }); - + // Add character field descriptions const charConfig = trackerConfig?.presentCharacters; if (charConfig?.customFields?.length > 0) { @@ -578,7 +578,7 @@ export function generateContextualSummary() { } } } - + // Add character stats descriptions const charStatsConfig = charConfig?.characterStats; if (charStatsConfig?.enabled && charStatsConfig?.customStats?.length > 0) { @@ -592,7 +592,7 @@ export function generateContextualSummary() { } } } - + // Inventory - format to match schema (use "items" for simplified mode) if (extensionSettings.showInventory && extensionSettings.inventoryV3) { const inv = extensionSettings.inventoryV3; @@ -613,14 +613,14 @@ export function generateContextualSummary() { } } } - + // Skills if (extensionSettings.showSkills && extensionSettings.skillsV2) { currentState.skills = extensionSettings.skillsV2; - + // Add skill category descriptions const skillCategories = trackerConfig?.userStats?.skillsSection?.customFields || []; - const categoriesWithDesc = skillCategories.filter(cat => + const categoriesWithDesc = skillCategories.filter(cat => typeof cat === 'object' && cat.enabled !== false && cat.description ); if (categoriesWithDesc.length > 0) { @@ -630,17 +630,17 @@ export function generateContextualSummary() { } } } - + // Quests if (extensionSettings.showQuests && extensionSettings.questsV2) { currentState.quests = extensionSettings.questsV2; } - + // Attributes and level (if RPG attributes are enabled and should be included) const showRPGAttributes = trackerConfig?.userStats?.showRPGAttributes; const alwaysSendAttributes = trackerConfig?.userStats?.alwaysSendAttributes; const shouldSendAttributes = alwaysSendAttributes || extensionSettings.lastDiceRoll; - + if (showRPGAttributes && shouldSendAttributes) { const rpgAttributes = trackerConfig?.userStats?.rpgAttributes || [ { id: 'str', name: 'STR', description: '', enabled: true }, @@ -651,7 +651,7 @@ export function generateContextualSummary() { { id: 'cha', name: 'CHA', description: '', enabled: true } ]; const enabledAttributes = rpgAttributes.filter(attr => attr && attr.enabled && attr.name && attr.id); - + if (enabledAttributes.length > 0) { currentState.attributes = {}; descriptions.attributes = {}; @@ -662,22 +662,22 @@ export function generateContextualSummary() { descriptions.attributes[attr.name] = attr.description; } } - + // Add level currentState.level = extensionSettings.level ?? 1; } } - + // Add descriptions metadata if any exist if (Object.keys(descriptions).length > 0) { currentState._descriptions = descriptions; } - + // Return JSON string if we have any data, otherwise empty string if (Object.keys(currentState).length > 0) { return JSON.stringify(currentState, null, 2); } - + return ''; } @@ -696,7 +696,7 @@ export function generateRPGPromptText() { // Build previous state as JSON const previousState = {}; - + // Stats if (extensionSettings.showUserStats) { const customStats = extensionSettings.trackerConfig?.userStats?.customStats?.filter(s => s?.enabled) || []; @@ -706,7 +706,7 @@ export function generateRPGPromptText() { previousState.stats[stat.name] = extensionSettings.userStats[stat.id] ?? 100; } } - + // Status const statusConfig = extensionSettings.trackerConfig?.userStats?.statusSection; if (statusConfig?.enabled) { @@ -726,12 +726,12 @@ export function generateRPGPromptText() { previousState.skills = extensionSettings.userStats.skills; } } - + // InfoBox if (extensionSettings.showInfoBox && extensionSettings.infoBoxData) { previousState.infoBox = extensionSettings.infoBoxData; } - + // Characters - format to match schema if (extensionSettings.showCharacterThoughts && extensionSettings.charactersData?.length > 0) { // Ensure characters match the expected schema format @@ -745,7 +745,7 @@ export function generateRPGPromptText() { return formatted; }); } - + // Inventory - format to match schema (use "items" for simplified mode) if (extensionSettings.showInventory && extensionSettings.inventoryV3) { const inv = extensionSettings.inventoryV3; @@ -766,22 +766,22 @@ export function generateRPGPromptText() { } } } - + // Skills if (extensionSettings.showSkills && extensionSettings.skillsV2) { previousState.skills = extensionSettings.skillsV2; } - + // Quests if (extensionSettings.showQuests && extensionSettings.questsV2) { previousState.quests = extensionSettings.questsV2; } - + // Attributes and level (if RPG attributes are enabled and should be included) const showRPGAttributes = trackerConfig?.userStats?.showRPGAttributes; const alwaysSendAttributes = trackerConfig?.userStats?.alwaysSendAttributes; const shouldSendAttributes = alwaysSendAttributes || extensionSettings.lastDiceRoll; - + if (showRPGAttributes && shouldSendAttributes) { const rpgAttributes = trackerConfig?.userStats?.rpgAttributes || [ { id: 'str', name: 'STR', description: '', enabled: true }, @@ -792,19 +792,19 @@ export function generateRPGPromptText() { { id: 'cha', name: 'CHA', description: '', enabled: true } ]; const enabledAttributes = rpgAttributes.filter(attr => attr && attr.enabled && attr.name && attr.id); - + if (enabledAttributes.length > 0) { previousState.attributes = {}; for (const attr of enabledAttributes) { const value = extensionSettings.classicStats?.[attr.id] ?? 10; previousState.attributes[attr.name] = value; } - + // Add level previousState.level = extensionSettings.level ?? 1; } } - + // Output as JSON if we have any data, otherwise indicate first update if (Object.keys(previousState).length > 0) { promptText += '```json\n';