mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Convert and import v2 character book embeds
This commit is contained in:
@@ -2408,6 +2408,9 @@
|
|||||||
<option id="set_character_world">
|
<option id="set_character_world">
|
||||||
<i class="fa-solid fa-globe"></i> Link to World Info
|
<i class="fa-solid fa-globe"></i> Link to World Info
|
||||||
</option>
|
</option>
|
||||||
|
<option id="import_character_info">
|
||||||
|
<i class="fa-solid fa-file-import"></i> Import Embedded World Info
|
||||||
|
</option>
|
||||||
<option id="set_chat_scenario">
|
<option id="set_chat_scenario">
|
||||||
Scenario Override
|
Scenario Override
|
||||||
</option>
|
</option>
|
||||||
|
@@ -29,6 +29,7 @@ import {
|
|||||||
world_info_match_whole_words,
|
world_info_match_whole_words,
|
||||||
world_names,
|
world_names,
|
||||||
world_info_character_strategy,
|
world_info_character_strategy,
|
||||||
|
importEmbeddedWorldInfo,
|
||||||
} from "./scripts/world-info.js";
|
} from "./scripts/world-info.js";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -4835,11 +4836,35 @@ export function select_selected_character(chid) {
|
|||||||
const world = characters[chid]?.data?.extensions?.world;
|
const world = characters[chid]?.data?.extensions?.world;
|
||||||
const worldSet = world && world_names.includes(world);
|
const worldSet = world && world_names.includes(world);
|
||||||
$('#set_character_world').toggleClass('world_set', worldSet);
|
$('#set_character_world').toggleClass('world_set', worldSet);
|
||||||
|
checkEmbeddedWorld(chid);
|
||||||
|
|
||||||
$("#form_create").attr("actiontype", "editcharacter");
|
$("#form_create").attr("actiontype", "editcharacter");
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkEmbeddedWorld(chid) {
|
||||||
|
$('#import_character_info').hide();
|
||||||
|
|
||||||
|
if (chid === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (characters[chid]?.data?.character_book) {
|
||||||
|
$('#import_character_info').data('chid', chid).show();
|
||||||
|
|
||||||
|
// Only show the alert once per character
|
||||||
|
const checkKey = `AlertWI_${characters[chid].avatar}`;
|
||||||
|
if (!localStorage.getItem(checkKey) && !(characters[chid]?.data?.extensions?.world)) {
|
||||||
|
toastr.info(
|
||||||
|
'To import and use it, select "Import Embedded World Info" in the Options menu.',
|
||||||
|
`${characters[chid].name} has an embedded World/Lorebook`,
|
||||||
|
{ timeOut: 10000, extendedTimeOut: 20000, positionClass: 'toast-top-center' },
|
||||||
|
);
|
||||||
|
localStorage.setItem(checkKey, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function select_rm_create() {
|
function select_rm_create() {
|
||||||
menu_type = "create";
|
menu_type = "create";
|
||||||
|
|
||||||
@@ -4890,6 +4915,7 @@ function select_rm_create() {
|
|||||||
$('#set_character_world').data('chid', undefined);
|
$('#set_character_world').data('chid', undefined);
|
||||||
$('#set_character_world').toggleClass('world_set', !!create_save.world);
|
$('#set_character_world').toggleClass('world_set', !!create_save.world);
|
||||||
updateFavButtonState(false);
|
updateFavButtonState(false);
|
||||||
|
checkEmbeddedWorld();
|
||||||
|
|
||||||
$("#form_create").attr("actiontype", "createcharacter");
|
$("#form_create").attr("actiontype", "createcharacter");
|
||||||
}
|
}
|
||||||
@@ -7492,7 +7518,7 @@ $(document).ready(function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#char-management-dropdown").on('change', (e) => {
|
$("#char-management-dropdown").on('change', async (e) => {
|
||||||
let target = $(e.target.selectedOptions).attr('id');
|
let target = $(e.target.selectedOptions).attr('id');
|
||||||
switch (target) {
|
switch (target) {
|
||||||
case 'set_character_world':
|
case 'set_character_world':
|
||||||
@@ -7511,6 +7537,10 @@ $(document).ready(function () {
|
|||||||
$('#export_format_popup').toggle();
|
$('#export_format_popup').toggle();
|
||||||
exportPopper.update();
|
exportPopper.update();
|
||||||
break;
|
break;
|
||||||
|
case 'import_character_info':
|
||||||
|
await importEmbeddedWorldInfo();
|
||||||
|
saveCharacterDebounced();
|
||||||
|
break;
|
||||||
case 'delete_button':
|
case 'delete_button':
|
||||||
popup_type = "del_ch";
|
popup_type = "del_ch";
|
||||||
callPopup(`
|
callPopup(`
|
||||||
|
@@ -274,10 +274,7 @@ function appendWorldEntry(name, data, entry) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
commentInput.val(entry.comment).trigger("input");
|
commentInput.val(entry.comment).trigger("input");
|
||||||
commentToggle.prop("checked", entry.selective).trigger("input");
|
commentToggle.prop("checked", entry.addMemo).trigger("input");
|
||||||
commentToggle.siblings(".checkbox_fancy").click(function () {
|
|
||||||
$(this).siblings("input").click();
|
|
||||||
});
|
|
||||||
|
|
||||||
// content
|
// content
|
||||||
const countTokensDebounced = debounce(function (that, value) {
|
const countTokensDebounced = debounce(function (that, value) {
|
||||||
@@ -784,6 +781,58 @@ function matchKeys(haystack, needle) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function convertCharacterBook(characterBook) {
|
||||||
|
const result = { entries: {} };
|
||||||
|
|
||||||
|
characterBook.entries.forEach((entry, index) => {
|
||||||
|
result.entries[index] = {
|
||||||
|
uid: entry.id || index,
|
||||||
|
key: entry.keys,
|
||||||
|
keysecondary: entry.secondary_keys || [],
|
||||||
|
comment: entry.comment || "",
|
||||||
|
content: entry.content,
|
||||||
|
constant: entry.constant || false,
|
||||||
|
selective: entry.selective || false,
|
||||||
|
order: entry.insertion_order,
|
||||||
|
position: entry.position === "before_char" ? world_info_position.before : world_info_position.after,
|
||||||
|
disable: !entry.enabled,
|
||||||
|
addMemo: entry.comment ? true : false,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function importEmbeddedWorldInfo() {
|
||||||
|
const chid = $('#import_character_info').data('chid');
|
||||||
|
|
||||||
|
if (chid === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bookName = characters[chid]?.data?.character_book?.name || `${characters[chid]?.name}'s Lorebook`;
|
||||||
|
const confirmationText = (`<h3>Are you sure you want to import "${bookName}"?</h3>`) + (world_names.includes(bookName) ? 'It will overwrite the World/Lorebook with the same name.' : '');
|
||||||
|
|
||||||
|
const confirmation = await callPopup(confirmationText, 'confirm');
|
||||||
|
|
||||||
|
if (!confirmation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const convertedBook = convertCharacterBook(characters[chid].data.character_book);
|
||||||
|
|
||||||
|
await saveWorldInfo(bookName, convertedBook, true);
|
||||||
|
await updateWorldInfoList();
|
||||||
|
$('#character_world').val(bookName).trigger('change');
|
||||||
|
|
||||||
|
toastr.success(`The world "${bookName}" has been imported and linked to the character successfully.`, 'World/Lorebook imported');
|
||||||
|
|
||||||
|
const newIndex = world_names.indexOf(bookName);
|
||||||
|
if (newIndex >= 0) {
|
||||||
|
$("#world_editor_select").val(newIndex).trigger('change');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
jQuery(() => {
|
jQuery(() => {
|
||||||
$("#world_info").on('change', async function () {
|
$("#world_info").on('change', async function () {
|
||||||
const selectedWorld = $("#world_info").find(":selected").val();
|
const selectedWorld = $("#world_info").find(":selected").val();
|
||||||
|
Reference in New Issue
Block a user