feat: expand character editor to show all v2/v3 character card fields
Added support for all v2/v3 character card fields in the character editor UI: - Description (10-row textarea) - Scenario - Message Example - Post-History Instructions - Alternate Greetings (one per line) - Tags (comma-separated) - Creator - Character Version - Creator Notes Updated frontend to load and save all fields, and backend update_character command to accept all new parameters. This allows imported v3 character cards to display their full details, especially the description field which contains the main character information. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -630,6 +630,15 @@ fn update_character(
|
|||||||
system_prompt: String,
|
system_prompt: String,
|
||||||
greeting: Option<String>,
|
greeting: Option<String>,
|
||||||
personality: Option<String>,
|
personality: Option<String>,
|
||||||
|
description: Option<String>,
|
||||||
|
scenario: Option<String>,
|
||||||
|
mes_example: Option<String>,
|
||||||
|
post_history: Option<String>,
|
||||||
|
alt_greetings: Option<Vec<String>>,
|
||||||
|
tags: Option<Vec<String>>,
|
||||||
|
creator: Option<String>,
|
||||||
|
character_version: Option<String>,
|
||||||
|
creator_notes: Option<String>,
|
||||||
avatar_path: Option<String>,
|
avatar_path: Option<String>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let mut character = get_active_character();
|
let mut character = get_active_character();
|
||||||
@@ -637,6 +646,15 @@ fn update_character(
|
|||||||
character.system_prompt = system_prompt;
|
character.system_prompt = system_prompt;
|
||||||
character.greeting = greeting;
|
character.greeting = greeting;
|
||||||
character.personality = personality;
|
character.personality = personality;
|
||||||
|
character.description = description;
|
||||||
|
character.scenario = scenario;
|
||||||
|
character.mes_example = mes_example;
|
||||||
|
character.post_history_instructions = post_history;
|
||||||
|
character.alternate_greetings = alt_greetings.unwrap_or_default();
|
||||||
|
character.tags = tags.unwrap_or_default();
|
||||||
|
character.creator = creator;
|
||||||
|
character.character_version = character_version;
|
||||||
|
character.creator_notes = creator_notes;
|
||||||
character.avatar_path = avatar_path;
|
character.avatar_path = avatar_path;
|
||||||
save_character(&character)
|
save_character(&character)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,6 +184,87 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="character-description">Description (Optional)</label>
|
||||||
|
<textarea
|
||||||
|
id="character-description"
|
||||||
|
placeholder="Detailed character description, appearance, background..."
|
||||||
|
rows="10"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="character-scenario">Scenario (Optional)</label>
|
||||||
|
<textarea
|
||||||
|
id="character-scenario"
|
||||||
|
placeholder="The setting or situation where the character exists..."
|
||||||
|
rows="4"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="character-mes-example">Message Example (Optional)</label>
|
||||||
|
<textarea
|
||||||
|
id="character-mes-example"
|
||||||
|
placeholder="Example dialogue from the character..."
|
||||||
|
rows="4"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="character-post-history">Post-History Instructions (Optional)</label>
|
||||||
|
<textarea
|
||||||
|
id="character-post-history"
|
||||||
|
placeholder="Instructions to apply after chat history..."
|
||||||
|
rows="3"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="character-alt-greetings">Alternate Greetings (Optional)</label>
|
||||||
|
<textarea
|
||||||
|
id="character-alt-greetings"
|
||||||
|
placeholder="One greeting per line..."
|
||||||
|
rows="3"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="character-tags">Tags (Optional)</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="character-tags"
|
||||||
|
placeholder="fantasy, adventure, comedy"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="character-creator">Creator (Optional)</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="character-creator"
|
||||||
|
placeholder="Card creator name"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="character-version">Character Version (Optional)</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="character-version"
|
||||||
|
placeholder="1.0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="character-creator-notes">Creator Notes (Optional)</label>
|
||||||
|
<textarea
|
||||||
|
id="character-creator-notes"
|
||||||
|
placeholder="Notes from the creator..."
|
||||||
|
rows="2"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="character-message" class="validation-message"></div>
|
<div id="character-message" class="validation-message"></div>
|
||||||
|
|
||||||
<button type="submit" id="save-character-btn" class="btn-primary">
|
<button type="submit" id="save-character-btn" class="btn-primary">
|
||||||
|
|||||||
29
src/main.js
29
src/main.js
@@ -1191,6 +1191,15 @@ async function loadCharacterSettings() {
|
|||||||
document.getElementById('character-system-prompt').value = character.system_prompt;
|
document.getElementById('character-system-prompt').value = character.system_prompt;
|
||||||
document.getElementById('character-greeting').value = character.greeting || '';
|
document.getElementById('character-greeting').value = character.greeting || '';
|
||||||
document.getElementById('character-personality').value = character.personality || '';
|
document.getElementById('character-personality').value = character.personality || '';
|
||||||
|
document.getElementById('character-description').value = character.description || '';
|
||||||
|
document.getElementById('character-scenario').value = character.scenario || '';
|
||||||
|
document.getElementById('character-mes-example').value = character.mes_example || '';
|
||||||
|
document.getElementById('character-post-history').value = character.post_history_instructions || '';
|
||||||
|
document.getElementById('character-alt-greetings').value = character.alternate_greetings ? character.alternate_greetings.join('\n') : '';
|
||||||
|
document.getElementById('character-tags').value = character.tags ? character.tags.join(', ') : '';
|
||||||
|
document.getElementById('character-creator').value = character.creator || '';
|
||||||
|
document.getElementById('character-version').value = character.character_version || '';
|
||||||
|
document.getElementById('character-creator-notes').value = character.creator_notes || '';
|
||||||
|
|
||||||
// Load avatar preview
|
// Load avatar preview
|
||||||
const avatarPreview = document.querySelector('.avatar-circle-large');
|
const avatarPreview = document.querySelector('.avatar-circle-large');
|
||||||
@@ -1222,6 +1231,17 @@ async function handleSaveCharacter(e) {
|
|||||||
const systemPrompt = document.getElementById('character-system-prompt').value.trim();
|
const systemPrompt = document.getElementById('character-system-prompt').value.trim();
|
||||||
const greeting = document.getElementById('character-greeting').value.trim() || null;
|
const greeting = document.getElementById('character-greeting').value.trim() || null;
|
||||||
const personality = document.getElementById('character-personality').value.trim() || null;
|
const personality = document.getElementById('character-personality').value.trim() || null;
|
||||||
|
const description = document.getElementById('character-description').value.trim() || null;
|
||||||
|
const scenario = document.getElementById('character-scenario').value.trim() || null;
|
||||||
|
const mesExample = document.getElementById('character-mes-example').value.trim() || null;
|
||||||
|
const postHistory = document.getElementById('character-post-history').value.trim() || null;
|
||||||
|
const altGreetingsText = document.getElementById('character-alt-greetings').value.trim();
|
||||||
|
const altGreetings = altGreetingsText ? altGreetingsText.split('\n').map(s => s.trim()).filter(s => s) : null;
|
||||||
|
const tagsText = document.getElementById('character-tags').value.trim();
|
||||||
|
const tags = tagsText ? tagsText.split(',').map(s => s.trim()).filter(s => s) : null;
|
||||||
|
const creator = document.getElementById('character-creator').value.trim() || null;
|
||||||
|
const characterVersion = document.getElementById('character-version').value.trim() || null;
|
||||||
|
const creatorNotes = document.getElementById('character-creator-notes').value.trim() || null;
|
||||||
const saveBtn = document.getElementById('save-character-btn');
|
const saveBtn = document.getElementById('save-character-btn');
|
||||||
const characterMsg = document.getElementById('character-message');
|
const characterMsg = document.getElementById('character-message');
|
||||||
|
|
||||||
@@ -1240,6 +1260,15 @@ async function handleSaveCharacter(e) {
|
|||||||
systemPrompt,
|
systemPrompt,
|
||||||
greeting,
|
greeting,
|
||||||
personality,
|
personality,
|
||||||
|
description,
|
||||||
|
scenario,
|
||||||
|
mesExample,
|
||||||
|
postHistory,
|
||||||
|
altGreetings,
|
||||||
|
tags,
|
||||||
|
creator,
|
||||||
|
characterVersion,
|
||||||
|
creatorNotes,
|
||||||
avatarPath: pendingAvatarPath
|
avatarPath: pendingAvatarPath
|
||||||
});
|
});
|
||||||
characterMsg.textContent = 'Character saved successfully';
|
characterMsg.textContent = 'Character saved successfully';
|
||||||
|
|||||||
Reference in New Issue
Block a user