diff --git a/public/index.html b/public/index.html index 4374ede3d..c75324f69 100644 --- a/public/index.html +++ b/public/index.html @@ -1835,7 +1835,7 @@

- World Selector + Global World Info / Lorebook Selector ? @@ -1853,7 +1853,7 @@

-
+
@@ -1887,6 +1887,18 @@
+
+
+ + +
+
- - + +
-
@@ -2783,6 +2797,27 @@
+
+
+
+

+ Select a World Info file for : +

+
+
+ A selected World Info / Lorebook will be bound to this character. + When generating an AI reply, it will be combined with the entries from a global World Info / Lorebook selector. + + +
+
+ +
+
+
+
diff --git a/public/script.js b/public/script.js index 7ae0b5ce1..cec1fdd01 100644 --- a/public/script.js +++ b/public/script.js @@ -30,6 +30,8 @@ import { world_info_recursive, world_info_case_sensitive, world_info_match_whole_words, + world_names, + world_info_character_strategy, } from "./scripts/world-info.js"; import { @@ -566,21 +568,24 @@ var is_advanced_char_open = false; var menu_type = ""; //what is selected in the menu var selected_button = ""; //which button pressed //create pole save -let create_save_name = ""; -let create_save_description = ""; -let create_save_creator_notes = ""; -let create_save_post_history_instructions = ""; -let create_save_character_version = ""; -let create_save_system_prompt = ""; -let create_save_tags = ""; -let create_save_creator = ""; -let create_save_personality = ""; -let create_save_first_message = ""; -let create_save_avatar = ""; -let create_save_scenario = ""; -let create_save_mes_example = ""; -let create_save_talkativeness = talkativeness_default; -let create_save_alternate_greetings = []; +let create_save = { + name: "", + description: "", + creator_notes: "", + post_history_instructions: "", + character_version: "", + system_prompt: "", + tags: "", + creator: "", + personality: "", + first_message: "", + avatar: "", + scenario: "", + mes_example: "", + world: "", + talkativeness: talkativeness_default, + alternate_greetings: [] +}; //animation right menu let animation_duration = 250; @@ -2014,7 +2019,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject, // Extension added strings //WI moved to top in order to allow it to hijack AN if necessary - let { worldInfoString, worldInfoBefore, worldInfoAfter } = getWorldInfoPrompt(chat2); + let { worldInfoString, worldInfoBefore, worldInfoAfter } = await getWorldInfoPrompt(chat2); let allAnchors = getAllExtensionPrompts(); const afterScenarioAnchor = getExtensionPrompt(extension_prompt_types.AFTER_SCENARIO); let zeroDepthAnchor = getExtensionPrompt(extension_prompt_types.IN_CHAT, 0, ' '); @@ -3615,7 +3620,7 @@ async function saveChat(chat_name, withMetadata) { async function read_avatar_load(input) { if (input.files && input.files[0]) { if (selected_button == "create") { - create_save_avatar = input.files; + create_save.avatar = input.files; } const e = await new Promise((resolve, reject) => { @@ -4389,6 +4394,7 @@ async function saveSettings(type) { world_info_recursive: world_info_recursive, world_info_case_sensitive: world_info_case_sensitive, world_info_match_whole_words: world_info_match_whole_words, + world_info_character_strategy: world_info_character_strategy, textgenerationwebui_settings: textgenerationwebui_settings, swipes: swipes, horde_settings: horde_settings, @@ -4768,6 +4774,7 @@ export function select_selected_character(chid) { $("#character_popup_text_h3").text(characters[chid].name); $("#character_name_pole").val(characters[chid].name); $("#description_textarea").val(characters[chid].description); + $("#character_world").val(characters[chid].data?.extensions?.world || ''); $("#creator_notes_textarea").val(characters[chid].data?.creator_notes || characters[chid].creatorcomment); $("#character_version_textarea").val(characters[chid].data?.character_version || ''); $("#system_prompt_textarea").val(characters[chid].data?.system_prompt || ''); @@ -4798,6 +4805,8 @@ export function select_selected_character(chid) { $("#name_div").addClass('displayNone'); $("#renameCharButton").css("display", ""); $('.open_alternate_greetings').data('chid', chid); + $('#set_character_world').data('chid', chid); + $('#set_character_world').toggleClass('world_set', !!(characters[chid].data?.extensions?.world)); $("#form_create").attr("actiontype", "editcharacter"); saveSettingsDebounced(); @@ -4808,8 +4817,8 @@ function select_rm_create() { //console.log('select_rm_Create() -- selected button: '+selected_button); if (selected_button == "create") { - if (create_save_avatar != "") { - $("#add_avatar_button").get(0).files = create_save_avatar; + if (create_save.avatar != "") { + $("#add_avatar_button").get(0).files = create_save.avatar; read_avatar_load($("#add_avatar_button").get(0)); } } @@ -4830,25 +4839,28 @@ function select_rm_create() { $("#rm_button_back").css("display", ""); $("#character_import_button").css("display", ""); $("#character_popup_text_h3").text("Create character"); - $("#character_name_pole").val(create_save_name); - $("#description_textarea").val(create_save_description); - $("#creator_notes_textarea").val(create_save_creator_notes); - $("#post_history_instructions_textarea").val(create_save_post_history_instructions); - $("#system_prompt_textarea").val(create_save_system_prompt); - $("#tags_textarea").val(create_save_tags); - $("#creator_textarea").val(create_save_creator); - $("#character_version_textarea").val(create_save_character_version); - $("#personality_textarea").val(create_save_personality); - $("#firstmessage_textarea").val(create_save_first_message); - $("#talkativeness_slider").val(create_save_talkativeness); - $("#scenario_pole").val(create_save_scenario); - $("#mes_example_textarea").val(create_save_mes_example.trim().length === 0 ? '' : create_save_mes_example); + $("#character_name_pole").val(create_save.name); + $("#description_textarea").val(create_save.description); + $('#character_world').val(create_save.world); + $("#creator_notes_textarea").val(create_save.creator_notes); + $("#post_history_instructions_textarea").val(create_save.post_history_instructions); + $("#system_prompt_textarea").val(create_save.system_prompt); + $("#tags_textarea").val(create_save.tags); + $("#creator_textarea").val(create_save.creator); + $("#character_version_textarea").val(create_save.character_version); + $("#personality_textarea").val(create_save.personality); + $("#firstmessage_textarea").val(create_save.first_message); + $("#talkativeness_slider").val(create_save.talkativeness); + $("#scenario_pole").val(create_save.scenario); + $("#mes_example_textarea").val(create_save.mes_example.trim().length === 0 ? '' : create_save.mes_example); $("#avatar_div").css("display", "flex"); $("#avatar_load_preview").attr("src", default_avatar); $("#renameCharButton").css('display', 'none'); $("#name_div").removeClass('displayNone'); $("#name_div").addClass('displayBlock'); $('.open_alternate_greetings').data('chid', undefined); + $('#set_character_world').data('chid', undefined); + $('#set_character_world').toggleClass('world_set', !!create_save.world); updateFavButtonState(false); $("#form_create").attr("actiontype", "createcharacter"); @@ -5222,6 +5234,50 @@ function updateAlternateGreetingsHintVisibility(root) { $(root).find('.alternate_grettings_hint').toggle(numberOfGreetings == 0); } +function openCharacterWorldPopup() { + const chid = $('#set_character_world').data('chid'); + + if (menu_type != 'create' && chid == undefined) { + toastr.error('Does not have an Id for this character in world select menu.'); + return; + } + + function onSelectCharacterWorld() { + const value = $(this).find('option:selected').val(); + const worldIndex = Number(value); + const name = !isNaN(worldIndex) ? world_names[worldIndex] : ''; + + $('#character_world').val(name); + + console.debug('Character world selected:', name); + + if (menu_type == 'create') { + create_save.world = name; + } else { + createOrEditCharacter(); + } + + $('#set_character_world').toggleClass('world_set', !!value); + } + + const name = (menu_type == 'create' ? create_save.name : characters[chid]?.data?.name) || 'Nameless'; + const worldId = (menu_type == 'create' ? create_save.world : characters[chid]?.data?.extensions?.world) || ''; + const template = $('#character_world_template .character_world').clone(); + const select = template.find('.character_world_info_selector'); + template.find('.character_name').text(name); + + world_names.forEach((item, i) => { + const option = document.createElement('option'); + option.value = i; + option.innerText = item; + option.selected = item === worldId; + select.append(option); + }); + + select.on('change', onSelectCharacterWorld); + callPopup(template, 'text'); +} + function openAlternateGreetings() { const chid = $('.open_alternate_greetings').data('chid'); @@ -5236,7 +5292,7 @@ function openAlternateGreetings() { } const template = $('#alternate_greetings_template .alternate_grettings').clone(); - const getArray = () => menu_type == 'create' ? create_save_alternate_greetings : characters[chid].data.alternate_greetings; + const getArray = () => menu_type == 'create' ? create_save.alternate_greetings : characters[chid].data.alternate_greetings; for (let index = 0; index < getArray().length; index++) { addAlternateGreeting(template, getArray()[index], index, getArray); @@ -5275,7 +5331,7 @@ function addAlternateGreeting(template, greeting, index, getArray) { async function createOrEditCharacter(e) { $("#rm_info_avatar").html(""); - let save_name = create_save_name; + let save_name = create_save.name; var formData = new FormData($("#form_create").get(0)); formData.set('fav', fav_ch_checked); if ($("#form_create").attr("actiontype") == "createcharacter") { @@ -5288,7 +5344,7 @@ async function createOrEditCharacter(e) { } formData.delete('alternate_greetings'); - for (const value of create_save_alternate_greetings) { + for (const value of create_save.alternate_greetings) { formData.append('alternate_greetings', value); } @@ -5306,21 +5362,22 @@ async function createOrEditCharacter(e) { success: async function (html) { $("#character_cross").trigger('click'); //closes the advanced character editing popup const fields = [ - { id: '#character_name_pole', callback: value => create_save_name = value }, - { id: '#description_textarea', callback: value => create_save_description = value }, - { id: '#creator_notes_textarea', callback: value => create_save_creator_notes = value }, - { id: '#character_version_textarea', callback: value => create_save_character_version = value }, - { id: '#post_history_instructions_textarea', callback: value => create_save_post_history_instructions = value }, - { id: '#system_prompt_textarea', callback: value => create_save_system_prompt = value }, - { id: '#tags_textarea', callback: value => create_save_tags = value }, - { id: '#creator_textarea', callback: value => create_save_creator = value }, - { id: '#personality_textarea', callback: value => create_save_personality = value }, - { id: '#firstmessage_textarea', callback: value => create_save_first_message = value }, - { id: '#talkativeness_slider', callback: value => create_save_talkativeness = value, defaultValue: talkativeness_default }, - { id: '#scenario_pole', callback: value => create_save_scenario = value }, - { id: '#mes_example_textarea', callback: value => create_save_mes_example = value }, + { id: '#character_name_pole', callback: value => create_save.name = value }, + { id: '#description_textarea', callback: value => create_save.description = value }, + { id: '#creator_notes_textarea', callback: value => create_save.creator_notes = value }, + { id: '#character_version_textarea', callback: value => create_save.character_version = value }, + { id: '#post_history_instructions_textarea', callback: value => create_save.post_history_instructions = value }, + { id: '#system_prompt_textarea', callback: value => create_save.system_prompt = value }, + { id: '#tags_textarea', callback: value => create_save.tags = value }, + { id: '#creator_textarea', callback: value => create_save.creator = value }, + { id: '#personality_textarea', callback: value => create_save.personality = value }, + { id: '#firstmessage_textarea', callback: value => create_save.first_message = value }, + { id: '#talkativeness_slider', callback: value => create_save.talkativeness = value, defaultValue: talkativeness_default }, + { id: '#scenario_pole', callback: value => create_save.scenario = value }, + { id: '#mes_example_textarea', callback: value => create_save.mes_example = value }, { id: '#character_json_data', callback: () => { } }, - { id: '#alternate_greetings_template', callback: value => create_save_alternate_greetings = value, defaultValue: [] }, + { id: '#alternate_greetings_template', callback: value => create_save.alternate_greetings = value, defaultValue: [] }, + { id: '#character_world', callback: value => create_save.world = value }, ]; fields.forEach(field => { @@ -5331,7 +5388,7 @@ async function createOrEditCharacter(e) { $("#character_popup_text_h3").text("Create character"); - create_save_avatar = ""; + create_save.avatar = ""; $("#create_button").removeAttr("disabled"); $("#add_avatar_button").replaceWith( @@ -6366,23 +6423,23 @@ $(document).ready(function () { $("#character_name_pole").on("input", function () { if (menu_type == "create") { - create_save_name = $("#character_name_pole").val(); + create_save.name = $("#character_name_pole").val(); } }); const elementsToUpdate = { - '#description_textarea': function () { create_save_description = $("#description_textarea").val(); }, - '#creator_notes_textarea': function () { create_save_creator_notes = $("#creator_notes_textarea").val(); }, - '#character_version_textarea': function () { create_save_character_version = $("#character_version_textarea").val(); }, - '#system_prompt_textarea': function () { create_save_system_prompt = $("#system_prompt_textarea").val(); }, - '#post_history_instructions_textarea': function () { create_save_post_history_instructions = $("#post_history_instructions_textarea").val(); }, - '#creator_textarea': function () { create_save_creator = $("#creator_textarea").val(); }, - '#tags_textarea': function () { create_save_tags = $("#tags_textarea").val(); }, - '#personality_textarea': function () { create_save_personality = $("#personality_textarea").val(); }, - '#scenario_pole': function () { create_save_scenario = $("#scenario_pole").val(); }, - '#mes_example_textarea': function () { create_save_mes_example = $("#mes_example_textarea").val(); }, - '#firstmessage_textarea': function () { create_save_first_message = $("#firstmessage_textarea").val(); }, - '#talkativeness_slider': function () { create_save_talkativeness = $("#talkativeness_slider").val(); }, + '#description_textarea': function () { create_save.description = $("#description_textarea").val(); }, + '#creator_notes_textarea': function () { create_save.creator_notes = $("#creator_notes_textarea").val(); }, + '#character_version_textarea': function () { create_save.character_version = $("#character_version_textarea").val(); }, + '#system_prompt_textarea': function () { create_save.system_prompt = $("#system_prompt_textarea").val(); }, + '#post_history_instructions_textarea': function () { create_save.post_history_instructions = $("#post_history_instructions_textarea").val(); }, + '#creator_textarea': function () { create_save.creator = $("#creator_textarea").val(); }, + '#tags_textarea': function () { create_save.tags = $("#tags_textarea").val(); }, + '#personality_textarea': function () { create_save.personality = $("#personality_textarea").val(); }, + '#scenario_pole': function () { create_save.scenario = $("#scenario_pole").val(); }, + '#mes_example_textarea': function () { create_save.mes_example = $("#mes_example_textarea").val(); }, + '#firstmessage_textarea': function () { create_save.first_message = $("#firstmessage_textarea").val(); }, + '#talkativeness_slider': function () { create_save.talkativeness = $("#talkativeness_slider").val(); }, }; Object.keys(elementsToUpdate).forEach(function (id) { @@ -7373,6 +7430,7 @@ $(document).ready(function () { $("#world_popup_entries_list").children().find('.up').click() }); $(document).on('click', '.open_alternate_greetings', openAlternateGreetings); + $('#set_character_world').on('click', openCharacterWorldPopup); $(document).keyup(function (e) { if (e.key === "Escape") { diff --git a/public/scripts/world-info.js b/public/scripts/world-info.js index 5738d5ec3..6f962e8a9 100644 --- a/public/scripts/world-info.js +++ b/public/scripts/world-info.js @@ -1,4 +1,4 @@ -import { saveSettings, callPopup, substituteParams, getTokenCount, getRequestHeaders, chat_metadata } from "../script.js"; +import { saveSettings, callPopup, substituteParams, getTokenCount, getRequestHeaders, chat_metadata, this_chid, characters } from "../script.js"; import { download, debounce, delay, initScrollHeight, resetScrollHeight } from "./utils.js"; import { getContext } from "./extensions.js"; import { metadata_keys } from "./extensions/floating-prompt/index.js"; @@ -11,6 +11,7 @@ export { world_info_recursive, world_info_case_sensitive, world_info_match_whole_words, + world_info_character_strategy, world_names, imported_world_name, checkWorldInfo, @@ -20,6 +21,12 @@ export { getWorldInfoPrompt, } +const world_info_insertion_strategy = { + evenly: 0, + character_first: 1, + global_first: 2, +} + let world_info = null; let world_names; let world_info_data = null; @@ -29,6 +36,7 @@ let is_world_edit_open = false; let world_info_recursive = false; let world_info_case_sensitive = false; let world_info_match_whole_words = false; +let world_info_character_strategy = world_info_insertion_strategy.evenly; let imported_world_name = ""; const saveWorldDebounced = debounce(async () => await _save(), 1000); const saveSettingsDebounced = debounce(() => saveSettings(), 1000); @@ -41,15 +49,14 @@ const world_info_position = { }; -function getWorldInfoPrompt(chat2) { +async function getWorldInfoPrompt(chat2) { let worldInfoString = "", worldInfoBefore = "", worldInfoAfter = ""; - if (world_info && world_info_data) { - const activatedWorldInfo = checkWorldInfo(chat2); - worldInfoBefore = activatedWorldInfo.worldInfoBefore; - worldInfoAfter = activatedWorldInfo.worldInfoAfter; - worldInfoString = worldInfoBefore + worldInfoAfter; - } + const activatedWorldInfo = await checkWorldInfo(chat2); + worldInfoBefore = activatedWorldInfo.worldInfoBefore; + worldInfoAfter = activatedWorldInfo.worldInfoAfter; + worldInfoString = worldInfoBefore + worldInfoAfter; + return { worldInfoString, worldInfoBefore, worldInfoAfter }; } @@ -64,6 +71,8 @@ function setWorldInfoSettings(settings, data) { world_info_case_sensitive = Boolean(settings.world_info_case_sensitive); if (settings.world_info_match_whole_words !== undefined) world_info_match_whole_words = Boolean(settings.world_info_match_whole_words); + if (settings.world_info_character_strategy !== undefined) + world_info_character_strategy = Number(settings.world_info_character_strategy); $("#world_info_depth_counter").text(world_info_depth); $("#world_info_depth").val(world_info_depth); @@ -75,6 +84,9 @@ function setWorldInfoSettings(settings, data) { $("#world_info_case_sensitive").prop('checked', world_info_case_sensitive); $("#world_info_match_whole_words").prop('checked', world_info_match_whole_words); + $(`#world_info_character_strategy option[value='${world_info_character_strategy}']`).prop('selected', true); + $("#world_info_character_strategy").val(world_info_character_strategy); + world_names = data.world_names?.length ? data.world_names : []; if (settings.world_info != undefined) { @@ -102,24 +114,27 @@ async function showWorldEditor() { is_world_edit_open = true; $("#world_popup_name").val(world_info); $("#world_popup").css("display", "flex"); - await loadWorldInfoData(); + world_info_data = await loadWorldInfoData(world_info); displayWorldEntries(world_info_data); } -async function loadWorldInfoData() { - if (!world_info) { +async function loadWorldInfoData(name) { + if (!name) { return; } const response = await fetch("/getworldinfo", { method: "POST", headers: getRequestHeaders(), - body: JSON.stringify({ name: world_info }), + body: JSON.stringify({ name: name }), }); if (response.ok) { - world_info_data = await response.json(); + const data = await response.json(); + return data; } + + return null; } async function updateWorldInfoList(importedWorldName) { @@ -533,11 +548,70 @@ function transformString(str) { return world_info_case_sensitive ? str : str.toLowerCase(); } -function checkWorldInfo(chat) { - if (world_info_data.entries.length == 0) { - return ""; +async function getCharacterLore() { + const name = characters[this_chid]?.data?.extensions?.world; + + if (!name) { + return []; } + if (!world_names.includes(name)) { + console.warn(`Character ${characters[this_chid]?.name} has invalid world info name: ${name}`); + return []; + } + + const data = await loadWorldInfoData(name); + const entries = data ? Object.keys(data.entries).map((x) => data.entries[x]) : []; + console.debug(`Character ${characters[this_chid]?.name} lore (${name}) has ${entries.length} world info entries`); + return entries; +} + +function getGlobalLore() { + if (!world_info || !world_info_data) { + return []; + } + + const entries = Object.keys(world_info_data.entries).map((x) => world_info_data.entries[x]); + console.debug(`Global world info has ${entries.length} entries`); + return entries; +} + + +async function getSortedEntries() { + try { + const globalLore = getGlobalLore(); + const characterLore = await getCharacterLore(); + + let entries; + const sortFn = (a, b) => b.order - a.order; + + switch (world_info_character_strategy) { + case world_info_insertion_strategy.evenly: + entries = [...globalLore, ...characterLore].sort(sortFn); + break; + case world_info_insertion_strategy.character_first: + entries = [...characterLore.sort(sortFn), ...globalLore.sort(sortFn)]; + break; + case world_info_insertion_strategy.global_first: + entries = [...globalLore.sort(sortFn), ...characterLore.sort(sortFn)]; + break; + default: + console.error(`Unknown insertion strategy: ${world_info_character_strategy}`); + entries = [...globalLore, ...characterLore].sort(sortFn); + break; + } + + console.debug(`Sorted ${entries.length} world lore entries using strategy ${world_info_character_strategy}`); + + return entries; + } + catch (e) { + console.error(e); + return []; + } +} + +async function checkWorldInfo(chat) { const context = getContext(); const messagesToLookBack = world_info_depth * 2; let textToScan = transformString(chat.slice(0, messagesToLookBack).join("")); @@ -547,9 +621,11 @@ function checkWorldInfo(chat) { let count = 0; let allActivatedEntries = new Set(); - const sortedEntries = Object.keys(world_info_data.entries) - .map((x) => world_info_data.entries[x]) - .sort((a, b) => b.order - a.order); + const sortedEntries = await getSortedEntries(); + + if (sortedEntries.length === 0) { + return { worldInfoBefore, worldInfoAfter }; + } while (needsToScan) { // Track how many times the loop has run @@ -558,12 +634,13 @@ function checkWorldInfo(chat) { let activatedNow = new Set(); for (let entry of sortedEntries) { - if (allActivatedEntries.has(entry.uid) || entry.disable == true || (count > 1 && world_info_recursive && entry.excludeRecursion)) { + if (allActivatedEntries.has(entry) || entry.disable == true || (count > 1 && world_info_recursive && entry.excludeRecursion)) { continue; } if (entry.constant) { - activatedNow.add(entry.uid); + activatedNow.add(entry); + continue; } if (Array.isArray(entry.key) && entry.key.length) { @@ -578,12 +655,12 @@ function checkWorldInfo(chat) { secondary: for (let keysecondary of entry.keysecondary) { const secondarySubstituted = substituteParams(keysecondary); if (secondarySubstituted && matchKeys(textToScan, secondarySubstituted.trim())) { - activatedNow.add(entry.uid); + activatedNow.add(entry); break secondary; } } } else { - activatedNow.add(entry.uid); + activatedNow.add(entry); break primary; } } @@ -593,7 +670,6 @@ function checkWorldInfo(chat) { needsToScan = world_info_recursive && activatedNow.size > 0; const newEntries = [...activatedNow] - .map((x) => world_info_data.entries[x]) .sort((a, b) => sortedEntries.indexOf(a) - sortedEntries.indexOf(b)); let ANInjectionTokens = 0; for (const entry of newEntries) { @@ -683,7 +759,7 @@ jQuery(() => { if (selectedWorld !== "None") { const worldIndex = Number(selectedWorld); world_info = !isNaN(worldIndex) ? world_names[worldIndex] : null; - await loadWorldInfoData(); + world_info_data = await loadWorldInfoData(world_info); } if (selectedWorld === "None") { hideWorldEditor(); } @@ -759,8 +835,12 @@ jQuery(() => { renameWorldInfo(); }); - $("#world_create_button").click(() => { - createNewWorldInfo(); + $("#world_create_button").on('click', async () => { + const confirm = await callPopup("

Create a new World Info?

", "confirm"); + + if (confirm) { + await createNewWorldInfo(); + } }); $(document).on("input", "#world_info_depth", function () { @@ -789,4 +869,9 @@ jQuery(() => { world_info_match_whole_words = !!$(this).prop('checked'); saveSettingsDebounced(); }); + + $('#world_info_character_strategy').on('change', function () { + world_info_character_strategy = $(this).val(); + saveSettingsDebounced(); + }) }); diff --git a/public/style.css b/public/style.css index 693ba179a..d6f910ff0 100644 --- a/public/style.css +++ b/public/style.css @@ -1190,6 +1190,10 @@ select option:not(:checked) { color: #c5b457 !important; } +.world_set { + color: #4b9c00 !important; +} + .displayBlock { display: block !important; } @@ -1338,6 +1342,10 @@ input[type=search]:focus::-webkit-search-cancel-button { gap: 5px !important; } +.gap10px { + gap: 10px !important; +} + .wide10pMinFit { width: 10%; min-width: fit-content; diff --git a/server.js b/server.js index bd3c9e60e..f05d62a20 100644 --- a/server.js +++ b/server.js @@ -830,6 +830,7 @@ function charaFormatData(data) { // ST extension fields to V2 object _.set(char, 'data.extensions.talkativeness', data.talkativeness); _.set(char, 'data.extensions.fav', data.fav == 'true'); + _.set(char, 'data.extensions.world', data.world || ''); //_.set(char, 'data.extensions.create_date', humanizedISO8601DateTime()); //_.set(char, 'data.extensions.avatar', 'none'); //_.set(char, 'data.extensions.chat', data.ch_name + ' - ' + humanizedISO8601DateTime());