feat: implement message examples usage from character cards
Add support for using mes_example field from character cards to teach the AI the character's voice and writing style. Examples are parsed, processed with template variable replacement, and injected into the context at a configurable position. Backend changes: - Extended RoleplaySettings with examples_enabled and examples_position fields - Implemented parse_message_examples() to parse <START>-delimited example blocks - Added example injection in build_api_messages() with position control - Integrated examples into token counter with accurate counting - Created update_examples_settings command for saving settings Frontend changes: - Added Message Examples UI controls in Author's Note tab - Checkbox to enable/disable examples - Dropdown to select injection position (after_system/before_history) - Save button with success/error feedback - Token breakdown now shows examples token count - Settings load/save integrated with roleplay panel Message examples help the AI understand character personality, speaking patterns, and response style by providing concrete examples of how the character should respond. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -153,9 +153,34 @@
|
||||
Enable Author's Note
|
||||
</label>
|
||||
</div>
|
||||
<button type="button" id="save-authors-note-btn" class="btn-primary" style="width: 100%;">
|
||||
<button type="button" id="save-authors-note-btn" class="btn-primary" style="width: 100%; margin-bottom: 20px;">
|
||||
Save Author's Note
|
||||
</button>
|
||||
|
||||
<!-- Message Examples Section -->
|
||||
<div class="form-group" style="border-top: 1px solid var(--border); padding-top: 16px;">
|
||||
<label>Message Examples</label>
|
||||
<p style="color: var(--text-secondary); font-size: 12px; margin-bottom: 8px;">
|
||||
Use character card's message examples to teach the AI the character's voice and style.
|
||||
</p>
|
||||
<label>
|
||||
<input type="checkbox" id="examples-enabled" />
|
||||
Enable Message Examples
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="examples-position">Examples Position</label>
|
||||
<select id="examples-position" style="width: 100%;">
|
||||
<option value="after_system">After System Prompt (Recommended)</option>
|
||||
<option value="before_history">Before Message History</option>
|
||||
</select>
|
||||
<p style="color: var(--text-secondary); font-size: 11px; margin-top: 4px;">
|
||||
Where to inject examples in the context. After system prompt works best for most models.
|
||||
</p>
|
||||
</div>
|
||||
<button type="button" id="save-examples-btn" class="btn-primary" style="width: 100%;">
|
||||
Save Examples Settings
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -671,6 +696,10 @@
|
||||
<span>Author's Note:</span>
|
||||
<span id="token-authorsnote">0</span>
|
||||
</div>
|
||||
<div class="token-breakdown-item">
|
||||
<span>Message Examples:</span>
|
||||
<span id="token-examples">0</span>
|
||||
</div>
|
||||
<div class="token-breakdown-item">
|
||||
<span>Message History:</span>
|
||||
<span id="token-history">0</span>
|
||||
|
||||
29
src/main.js
29
src/main.js
@@ -1561,6 +1561,7 @@ function setupAppControls() {
|
||||
document.getElementById('add-worldinfo-btn').addEventListener('click', handleAddWorldInfoEntry);
|
||||
document.getElementById('save-authors-note-btn').addEventListener('click', handleSaveAuthorsNote);
|
||||
document.getElementById('save-persona-btn').addEventListener('click', handleSavePersona);
|
||||
document.getElementById('save-examples-btn').addEventListener('click', handleSaveExamples);
|
||||
|
||||
// Setup recursion depth change handler
|
||||
document.getElementById('recursion-depth').addEventListener('change', handleRecursionDepthChange);
|
||||
@@ -1622,6 +1623,7 @@ async function updateTokenCount() {
|
||||
document.getElementById('token-persona').textContent = tokenData.persona;
|
||||
document.getElementById('token-worldinfo').textContent = tokenData.world_info;
|
||||
document.getElementById('token-authorsnote').textContent = tokenData.authors_note;
|
||||
document.getElementById('token-examples').textContent = tokenData.message_examples;
|
||||
document.getElementById('token-history').textContent = tokenData.message_history;
|
||||
document.getElementById('token-input').textContent = tokenData.current_input;
|
||||
document.getElementById('token-total-detail').textContent = tokenData.total;
|
||||
@@ -2012,6 +2014,10 @@ async function loadRoleplaySettings() {
|
||||
document.getElementById('persona-description').value = settings.persona_description || '';
|
||||
document.getElementById('persona-enabled').checked = settings.persona_enabled || false;
|
||||
|
||||
// Load Message Examples
|
||||
document.getElementById('examples-enabled').checked = settings.examples_enabled || false;
|
||||
document.getElementById('examples-position').value = settings.examples_position || 'after_system';
|
||||
|
||||
// Load Presets
|
||||
await loadPresets();
|
||||
} catch (error) {
|
||||
@@ -2243,6 +2249,29 @@ async function handleSavePersona() {
|
||||
}
|
||||
}
|
||||
|
||||
// Save Message Examples Settings
|
||||
async function handleSaveExamples() {
|
||||
if (!currentCharacter) return;
|
||||
|
||||
const enabled = document.getElementById('examples-enabled').checked;
|
||||
const position = document.getElementById('examples-position').value;
|
||||
|
||||
try {
|
||||
await invoke('update_examples_settings', {
|
||||
characterId: currentCharacter.id,
|
||||
enabled,
|
||||
position
|
||||
});
|
||||
|
||||
// Show success message
|
||||
setStatus('Message Examples settings saved', 'success');
|
||||
setTimeout(() => setStatus('Ready'), 2000);
|
||||
} catch (error) {
|
||||
console.error('Failed to save Message Examples settings:', error);
|
||||
setStatus('Failed to save Message Examples settings', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// Handle recursion depth change
|
||||
async function handleRecursionDepthChange() {
|
||||
if (!currentCharacter) return;
|
||||
|
||||
Reference in New Issue
Block a user