Merge branch 'staging' into custom_request_stop_string_cleanup
| @@ -2745,7 +2745,6 @@ | ||
| 2745 | 2745 | <optgroup> |
| 2746 | 2746 | <option value="01ai">01.AI (Yi)</option> |
| 2747 | 2747 | <option value="ai21">AI21</option> |
| 2748 | - <option value="blockentropy">Block Entropy</option> | |
| 2749 | 2748 | <option value="claude">Claude</option> |
| 2750 | 2749 | <option value="cohere">Cohere</option> |
| 2751 | 2750 | <option value="deepseek">DeepSeek</option> |
| @@ -3375,20 +3374,6 @@ | ||
| 3375 | 3374 | </select> |
| 3376 | 3375 | </div> |
| 3377 | 3376 | </form> |
| 3378 | - <form id="blockentropy_form" data-source="blockentropy"> | |
| 3379 | - <h4 data-i18n="Block Entropy API Key">Block Entropy API Key</h4> | |
| 3380 | - <div class="flex-container"> | |
| 3381 | - <input id="api_key_blockentropy" name="api_key_blockentropy" class="text_pole flex1" value="" type="text" autocomplete="off"> | |
| 3382 | - <div title="Clear your API key" data-i18n="[title]Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_blockentropy"></div> | |
| 3383 | - </div> | |
| 3384 | - <div data-for="api_key_blockentropy" class="neutral_warning" data-i18n="For privacy reasons, your API key will be hidden after you reload the page."> | |
| 3385 | - For privacy reasons, your API key will be hidden after you reload the page. | |
| 3386 | - </div> | |
| 3387 | - <h4 data-i18n="Select a Model">Select a Model</h4> | |
| 3388 | - <div class="flex-container"> | |
| 3389 | - <select id="model_blockentropy_select" class="text_pole"></select> | |
| 3390 | - </div> | |
| 3391 | - </form> | |
| 3392 | 3377 | <form id="custom_form" data-source="custom"> |
| 3393 | 3378 | <h4 data-i18n="Custom Endpoint (Base URL)">Custom Endpoint (Base URL)</h4> |
| 3394 | 3379 | <div class="flex-container"> |
| @@ -6013,6 +5998,7 @@ | ||
| 6013 | 5998 | </div> |
| 6014 | 5999 | </div> |
| 6015 | 6000 | </div> |
| 6001 | + <i class="menu_button move_entry_button fa-solid fa-right-left" title="Move Entry to Another Lorebook" data-i18n="[title]Move Entry to Another Lorebook"></i> | |
| 6016 | 6002 | <i class="menu_button duplicate_entry_button fa-solid fa-paste" title="Duplicate world info entry" data-i18n="[title]Duplicate world info entry" type="submit" value=""></i> |
| 6017 | 6003 | <i class="menu_button delete_entry_button fa-solid fa-trash-can" title="Delete world info entry" data-i18n="[title]Delete world info entry" type="submit" value=""></i> |
| 6018 | 6004 | </div> |
| @@ -6101,9 +6087,12 @@ | ||
| 6101 | 6087 | <label for="content "> |
| 6102 | 6088 | <small> |
| 6103 | 6089 | <span class="alignitemscenter flex-container flexnowrap wide100p justifySpaceBetween"> |
| 6104 | 6090 | <span data-i18n="Content" class="alignitemscenter flex-container flexNoGap mdhotkey_location"> |
| 6091 | + <span data-i18n="Content" class="mdhotkey_location"> | |
| 6105 | 6092 | Content |
| 6106 | 6093 | </span> |
| 6094 | + <i class="editor_maximize fa-solid fa-maximize right_menu_button" title="Expand the editor" data-i18n="[title]Expand the editor"></i> | |
| 6095 | + </span> | |
| 6107 | 6096 | <span> |
| 6108 | 6097 | (<span data-i18n="extension_token_counter">Tokens:</span> <span class="world_entry_form_token_counter" data-first-run="true">counting...</span>) |
| 6109 | 6098 | <span class="world_entry_form_uid_value" data-first-run="true"></span> |
| @@ -174,7 +174,7 @@ import { | ||
| 174 | 174 | saveBase64AsFile, |
| 175 | 175 | uuidv4, |
| 176 | 176 | } from './scripts/utils.js'; |
| 177 | 177 | import { debounce_timeout, IGNORE_SYMBOL } from './scripts/constants.js'; |
| 178 | 178 | |
| 179 | 179 | import { doDailyExtensionUpdatesCheck, extension_settings, initExtensions, loadExtensionSettings, runGenerationInterceptors, saveMetadataDebounced } from './scripts/extensions.js'; |
| 180 | 180 | import { COMMENT_NAME_DEFAULT, executeSlashCommandsOnChatInput, getSlashCommandsHelp, initDefaultSlashCommands, isExecutingCommandsFromChatInput, pauseScriptExecution, processChatSlashCommands, stopScriptExecution } from './scripts/slash-commands.js'; |
| @@ -5301,6 +5301,12 @@ function formatMessageHistoryItem(chatItem, isInstruct, forceOutputSequence) { | ||
| 5301 | 5301 | const itemName = chatItem.is_user ? chatItem['name'] : characterName; |
| 5302 | 5302 | const shouldPrependName = !isNarratorType; |
| 5303 | 5303 | |
| 5304 | + // If this symbol flag is set, completely ignore the message. | |
| 5305 | + // This can be used to hide messages without affecting the number of messages in the chat. | |
| 5306 | + if (chatItem.extra?.[IGNORE_SYMBOL]) { | |
| 5307 | + return ''; | |
| 5308 | + } | |
| 5309 | + | |
| 5304 | 5310 | // Don't include a name if it's empty |
| 5305 | 5311 | let textResult = chatItem?.name && shouldPrependName ? `${itemName}: ${chatItem.mes}\n` : `${chatItem.mes}\n`; |
| 5306 | 5312 | |
| @@ -407,7 +407,6 @@ function RA_autoconnect(PrevApi) { | ||
| 407 | 407 | || (secret_state[SECRET_KEYS.PERPLEXITY] && oai_settings.chat_completion_source == chat_completion_sources.PERPLEXITY) |
| 408 | 408 | || (secret_state[SECRET_KEYS.GROQ] && oai_settings.chat_completion_source == chat_completion_sources.GROQ) |
| 409 | 409 | || (secret_state[SECRET_KEYS.ZEROONEAI] && oai_settings.chat_completion_source == chat_completion_sources.ZEROONEAI) |
| 410 | - || (secret_state[SECRET_KEYS.BLOCKENTROPY] && oai_settings.chat_completion_source == chat_completion_sources.BLOCKENTROPY) | |
| 411 | 410 | || (secret_state[SECRET_KEYS.NANOGPT] && oai_settings.chat_completion_source == chat_completion_sources.NANOGPT) |
| 412 | 411 | || (secret_state[SECRET_KEYS.DEEPSEEK] && oai_settings.chat_completion_source == chat_completion_sources.DEEPSEEK) |
| 413 | 412 | || (isValidUrl(oai_settings.custom_url) && oai_settings.chat_completion_source == chat_completion_sources.CUSTOM) |
| @@ -14,3 +14,11 @@ export const debounce_timeout = { | ||
| 14 | 14 | /** [5 sec] For delayed tasks, like auto-saving or completing batch operations that need a significant pause. */ |
| 15 | 15 | extended: 5000, |
| 16 | 16 | }; |
| 17 | + | |
| 18 | +/** | |
| 19 | + * Used as an ephemeral key in message extra metadata. | |
| 20 | + * When set, the message will be excluded from generation | |
| 21 | + * prompts without affecting the number of chat messages, | |
| 22 | + * which is needed to preserve world info timed effects. | |
| 23 | + */ | |
| 24 | +export const IGNORE_SYMBOL = Symbol.for('ignore'); | |
| @@ -794,6 +794,16 @@ async function showExtensionsDetails() { | ||
| 794 | 794 | }; |
| 795 | 795 | |
| 796 | 796 | /** @type {import('./popup.js').CustomPopupButton} */ |
| 797 | + const updateEnabledOnlyButton = { | |
| 798 | + text: t`Update enabled only`, | |
| 799 | + action: async () => { | |
| 800 | + requiresReload = true; | |
| 801 | + await autoUpdateExtensions(false); | |
| 802 | + await popup.complete(POPUP_RESULT.AFFIRMATIVE); | |
| 803 | + }, | |
| 804 | + }; | |
| 805 | + | |
| 806 | + /** @type {import('./popup.js').CustomPopupButton} */ | |
| 797 | 807 | const sortOrderButton = { |
| 798 | 808 | text: sortByName ? t`Sort: Display Name` : t`Sort: Loading Order`, |
| 799 | 809 | action: async () => { |
| @@ -809,7 +819,7 @@ async function showExtensionsDetails() { | ||
| 809 | 819 | okButton: t`Close`, |
| 810 | 820 | wide: true, |
| 811 | 821 | large: true, |
| 812 | 822 | customButtons: [sortOrderButton, updateEnabledOnlyButton, updateAllButton], |
| 813 | 823 | allowVerticalScrolling: true, |
| 814 | 824 | onClosing: async () => { |
| 815 | 825 | if (waitingForSave) { |
| @@ -1196,7 +1206,7 @@ async function checkForUpdatesManual(sortFn, abortSignal) { | ||
| 1196 | 1206 | } |
| 1197 | 1207 | |
| 1198 | 1208 | /** |
| 1199 | 1209 | * Checks if there are updates available for enabled 3rd-party extensions. |
| 1200 | 1210 | * @param {boolean} force Skip nag check |
| 1201 | 1211 | * @returns {Promise<any>} |
| 1202 | 1212 | */ |
| @@ -1218,6 +1228,11 @@ async function checkForExtensionUpdates(force) { | ||
| 1218 | 1228 | const promises = []; |
| 1219 | 1229 | |
| 1220 | 1230 | for (const [id, manifest] of Object.entries(manifests)) { |
| 1231 | + const isDisabled = extension_settings.disabledExtensions.includes(id); | |
| 1232 | + if (isDisabled) { | |
| 1233 | + console.debug(`Skipping extension: ${manifest.display_name} (${id}) for non-admin user`); | |
| 1234 | + continue; | |
| 1235 | + } | |
| 1221 | 1236 | const isGlobal = getExtensionType(id) === 'global'; |
| 1222 | 1237 | if (isGlobal && !isCurrentUserAdmin) { |
| 1223 | 1238 | console.debug(`Skipping global extension: ${manifest.display_name} (${id}) for non-admin user`); |
| @@ -1247,8 +1262,8 @@ async function checkForExtensionUpdates(force) { | ||
| 1247 | 1262 | } |
| 1248 | 1263 | |
| 1249 | 1264 | /** |
| 1250 | 1265 | * Updates all enabled 3rd-party extensions that have auto-update enabled. |
| 1251 | 1266 | * @param {boolean} forceAll Force update allInclude evendisabled ifand not auto-updating |
| 1252 | 1267 | * @returns {Promise<void>} |
| 1253 | 1268 | */ |
| 1254 | 1269 | async function autoUpdateExtensions(forceAll) { |
| @@ -1260,6 +1275,11 @@ async function autoUpdateExtensions(forceAll) { | ||
| 1260 | 1275 | const isCurrentUserAdmin = isAdmin(); |
| 1261 | 1276 | const promises = []; |
| 1262 | 1277 | for (const [id, manifest] of Object.entries(manifests)) { |
| 1278 | + const isDisabled = extension_settings.disabledExtensions.includes(id); | |
| 1279 | + if (!forceAll && isDisabled) { | |
| 1280 | + console.debug(`Skipping extension: ${manifest.display_name} (${id}) for non-admin user`); | |
| 1281 | + continue; | |
| 1282 | + } | |
| 1263 | 1283 | const isGlobal = getExtensionType(id) === 'global'; |
| 1264 | 1284 | if (isGlobal && !isCurrentUserAdmin) { |
| 1265 | 1285 | console.debug(`Skipping global extension: ${manifest.display_name} (${id}) for non-admin user`); |
| @@ -77,7 +77,6 @@ const sources = { | ||
| 77 | 77 | drawthings: 'drawthings', |
| 78 | 78 | pollinations: 'pollinations', |
| 79 | 79 | stability: 'stability', |
| 80 | - blockentropy: 'blockentropy', | |
| 81 | 80 | huggingface: 'huggingface', |
| 82 | 81 | nanogpt: 'nanogpt', |
| 83 | 82 | bfl: 'bfl', |
| @@ -1300,7 +1299,6 @@ async function onModelChange() { | ||
| 1300 | 1299 | sources.togetherai, |
| 1301 | 1300 | sources.pollinations, |
| 1302 | 1301 | sources.stability, |
| 1303 | - sources.blockentropy, | |
| 1304 | 1302 | sources.huggingface, |
| 1305 | 1303 | sources.nanogpt, |
| 1306 | 1304 | sources.bfl, |
| @@ -1511,9 +1509,6 @@ async function loadSamplers() { | ||
| 1511 | 1509 | case sources.stability: |
| 1512 | 1510 | samplers = ['N/A']; |
| 1513 | 1511 | break; |
| 1514 | - case sources.blockentropy: | |
| 1515 | - samplers = ['N/A']; | |
| 1516 | - break; | |
| 1517 | 1512 | case sources.huggingface: |
| 1518 | 1513 | samplers = ['N/A']; |
| 1519 | 1514 | break; |
| @@ -1701,9 +1696,6 @@ async function loadModels() { | ||
| 1701 | 1696 | case sources.stability: |
| 1702 | 1697 | models = await loadStabilityModels(); |
| 1703 | 1698 | break; |
| 1704 | - case sources.blockentropy: | |
| 1705 | - models = await loadBlockEntropyModels(); | |
| 1706 | - break; | |
| 1707 | 1699 | case sources.huggingface: |
| 1708 | 1700 | models = [{ value: '', text: '<Enter Model ID above>' }]; |
| 1709 | 1701 | break; |
| @@ -1799,26 +1791,6 @@ async function loadTogetherAIModels() { | ||
| 1799 | 1791 | return []; |
| 1800 | 1792 | } |
| 1801 | 1793 | |
| 1802 | -async function loadBlockEntropyModels() { | |
| 1803 | - if (!secret_state[SECRET_KEYS.BLOCKENTROPY]) { | |
| 1804 | - console.debug('Block Entropy API key is not set.'); | |
| 1805 | - return []; | |
| 1806 | - } | |
| 1807 | - | |
| 1808 | - const result = await fetch('/api/sd/blockentropy/models', { | |
| 1809 | - method: 'POST', | |
| 1810 | - headers: getRequestHeaders(), | |
| 1811 | - }); | |
| 1812 | - console.log(result); | |
| 1813 | - if (result.ok) { | |
| 1814 | - const data = await result.json(); | |
| 1815 | - console.log(data); | |
| 1816 | - return data; | |
| 1817 | - } | |
| 1818 | - | |
| 1819 | - return []; | |
| 1820 | -} | |
| 1821 | - | |
| 1822 | 1794 | async function loadNanoGPTModels() { |
| 1823 | 1795 | if (!secret_state[SECRET_KEYS.NANOGPT]) { |
| 1824 | 1796 | console.debug('NanoGPT API key is not set.'); |
| @@ -2097,9 +2069,6 @@ async function loadSchedulers() { | ||
| 2097 | 2069 | case sources.stability: |
| 2098 | 2070 | schedulers = ['N/A']; |
| 2099 | 2071 | break; |
| 2100 | - case sources.blockentropy: | |
| 2101 | - schedulers = ['N/A']; | |
| 2102 | - break; | |
| 2103 | 2072 | case sources.huggingface: |
| 2104 | 2073 | schedulers = ['N/A']; |
| 2105 | 2074 | break; |
| @@ -2188,9 +2157,6 @@ async function loadVaes() { | ||
| 2188 | 2157 | case sources.stability: |
| 2189 | 2158 | vaes = ['N/A']; |
| 2190 | 2159 | break; |
| 2191 | - case sources.blockentropy: | |
| 2192 | - vaes = ['N/A']; | |
| 2193 | - break; | |
| 2194 | 2160 | case sources.huggingface: |
| 2195 | 2161 | vaes = ['N/A']; |
| 2196 | 2162 | break; |
| @@ -2757,9 +2723,6 @@ async function sendGenerationRequest(generationType, prompt, additionalNegativeP | ||
| 2757 | 2723 | case sources.stability: |
| 2758 | 2724 | result = await generateStabilityImage(prefixedPrompt, negativePrompt, signal); |
| 2759 | 2725 | break; |
| 2760 | - case sources.blockentropy: | |
| 2761 | - result = await generateBlockEntropyImage(prefixedPrompt, negativePrompt, signal); | |
| 2762 | - break; | |
| 2763 | 2726 | case sources.huggingface: |
| 2764 | 2727 | result = await generateHuggingFaceImage(prefixedPrompt, signal); |
| 2765 | 2728 | break; |
| @@ -2828,40 +2791,6 @@ async function generateTogetherAIImage(prompt, negativePrompt, signal) { | ||
| 2828 | 2791 | } |
| 2829 | 2792 | } |
| 2830 | 2793 | |
| 2831 | -async function generateBlockEntropyImage(prompt, negativePrompt, signal) { | |
| 2832 | - const result = await fetch('/api/sd/blockentropy/generate', { | |
| 2833 | - method: 'POST', | |
| 2834 | - headers: getRequestHeaders(), | |
| 2835 | - signal: signal, | |
| 2836 | - body: JSON.stringify({ | |
| 2837 | - prompt: prompt, | |
| 2838 | - negative_prompt: negativePrompt, | |
| 2839 | - model: extension_settings.sd.model, | |
| 2840 | - steps: extension_settings.sd.steps, | |
| 2841 | - width: extension_settings.sd.width, | |
| 2842 | - height: extension_settings.sd.height, | |
| 2843 | - seed: extension_settings.sd.seed >= 0 ? extension_settings.sd.seed : undefined, | |
| 2844 | - }), | |
| 2845 | - }); | |
| 2846 | - | |
| 2847 | - if (result.ok) { | |
| 2848 | - const data = await result.json(); | |
| 2849 | - | |
| 2850 | - // Default format is 'jpg' | |
| 2851 | - let format = 'jpg'; | |
| 2852 | - | |
| 2853 | - // Check if a format is specified in the result | |
| 2854 | - if (data.format) { | |
| 2855 | - format = data.format.toLowerCase(); | |
| 2856 | - } | |
| 2857 | - | |
| 2858 | - return { format: format, data: data.images[0] }; | |
| 2859 | - } else { | |
| 2860 | - const text = await result.text(); | |
| 2861 | - throw new Error(text); | |
| 2862 | - } | |
| 2863 | -} | |
| 2864 | - | |
| 2865 | 2794 | /** |
| 2866 | 2795 | * Generates an image using the Pollinations API. |
| 2867 | 2796 | * @param {string} prompt - The main instruction used to guide the image generation. |
| @@ -3845,8 +3774,6 @@ function isValidState() { | ||
| 3845 | 3774 | return true; |
| 3846 | 3775 | case sources.stability: |
| 3847 | 3776 | return secret_state[SECRET_KEYS.STABILITY]; |
| 3848 | - case sources.blockentropy: | |
| 3849 | - return secret_state[SECRET_KEYS.BLOCKENTROPY]; | |
| 3850 | 3777 | case sources.huggingface: |
| 3851 | 3778 | return secret_state[SECRET_KEYS.HUGGINGFACE]; |
| 3852 | 3779 | case sources.nanogpt: |
| @@ -38,7 +38,6 @@ | ||
| 38 | 38 | <label for="sd_source" data-i18n="Source">Source</label> |
| 39 | 39 | <select id="sd_source"> |
| 40 | 40 | <option value="bfl">BFL (Black Forest Labs)</option> |
| 41 | - <option value="blockentropy">Block Entropy</option> | |
| 42 | 41 | <option value="comfy">ComfyUI</option> |
| 43 | 42 | <option value="drawthings">DrawThings HTTP API</option> |
| 44 | 43 | <option value="extras">Extras API (deprecated)</option> |
| @@ -422,7 +421,7 @@ | ||
| 422 | 421 | </label> |
| 423 | 422 | </div> |
| 424 | 423 | |
| 425 | 424 | <div data-sd-source="novel,togetherai,pollinations,comfy,drawthings,vlad,auto,horde,extras,stability,blockentropy,bfl" class="marginTop5"> |
| 426 | 425 | <label for="sd_seed"> |
| 427 | 426 | <span data-i18n="Seed">Seed</span> |
| 428 | 427 | <small data-i18n="(-1 for random)">(-1 for random)</small> |
| @@ -75,6 +75,7 @@ import { Popup, POPUP_RESULT } from './popup.js'; | ||
| 75 | 75 | import { t } from './i18n.js'; |
| 76 | 76 | import { ToolManager } from './tool-calling.js'; |
| 77 | 77 | import { accountStorage } from './util/AccountStorage.js'; |
| 78 | +import { IGNORE_SYMBOL } from './constants.js'; | |
| 78 | 79 | |
| 79 | 80 | export { |
| 80 | 81 | openai_messages_count, |
| @@ -119,7 +120,6 @@ const default_bias_presets = { | ||
| 119 | 120 | const max_2k = 2047; |
| 120 | 121 | const max_4k = 4095; |
| 121 | 122 | const max_8k = 8191; |
| 122 | -const max_12k = 12287; | |
| 123 | 123 | const max_16k = 16383; |
| 124 | 124 | const max_32k = 32767; |
| 125 | 125 | const max_64k = 65535; |
| @@ -182,7 +182,6 @@ export const chat_completion_sources = { | ||
| 182 | 182 | PERPLEXITY: 'perplexity', |
| 183 | 183 | GROQ: 'groq', |
| 184 | 184 | ZEROONEAI: '01ai', |
| 185 | - BLOCKENTROPY: 'blockentropy', | |
| 186 | 185 | NANOGPT: 'nanogpt', |
| 187 | 186 | DEEPSEEK: 'deepseek', |
| 188 | 187 | }; |
| @@ -258,7 +257,6 @@ export const settingsToUpdate = { | ||
| 258 | 257 | nanogpt_model: ['#model_nanogpt_select', 'nanogpt_model', false], |
| 259 | 258 | deepseek_model: ['#model_deepseek_select', 'deepseek_model', false], |
| 260 | 259 | zerooneai_model: ['#model_01ai_select', 'zerooneai_model', false], |
| 261 | - blockentropy_model: ['#model_blockentropy_select', 'blockentropy_model', false], | |
| 262 | 260 | custom_model: ['#custom_model_id', 'custom_model', false], |
| 263 | 261 | custom_url: ['#custom_api_url_text', 'custom_url', false], |
| 264 | 262 | custom_include_body: ['#custom_include_body', 'custom_include_body', false], |
| @@ -346,7 +344,6 @@ const default_settings = { | ||
| 346 | 344 | groq_model: 'llama-3.3-70b-versatile', |
| 347 | 345 | nanogpt_model: 'gpt-4o-mini', |
| 348 | 346 | zerooneai_model: 'yi-large', |
| 349 | - blockentropy_model: 'be-70b-base-llama3.1', | |
| 350 | 347 | deepseek_model: 'deepseek-chat', |
| 351 | 348 | custom_model: '', |
| 352 | 349 | custom_url: '', |
| @@ -427,7 +424,6 @@ const oai_settings = { | ||
| 427 | 424 | groq_model: 'llama-3.1-70b-versatile', |
| 428 | 425 | nanogpt_model: 'gpt-4o-mini', |
| 429 | 426 | zerooneai_model: 'yi-large', |
| 430 | - blockentropy_model: 'be-70b-base-llama3.1', | |
| 431 | 427 | deepseek_model: 'deepseek-chat', |
| 432 | 428 | custom_model: '', |
| 433 | 429 | custom_url: '', |
| @@ -527,6 +523,13 @@ function setOpenAIMessages(chat) { | ||
| 527 | 523 | let role = chat[j]['is_user'] ? 'user' : 'assistant'; |
| 528 | 524 | let content = chat[j]['mes']; |
| 529 | 525 | |
| 526 | + // If this symbol flag is set, completely ignore the message. | |
| 527 | + // This can be used to hide messages without affecting the number of messages in the chat. | |
| 528 | + if (chat[j].extra?.[IGNORE_SYMBOL]) { | |
| 529 | + j++; | |
| 530 | + continue; | |
| 531 | + } | |
| 532 | + | |
| 530 | 533 | // 100% legal way to send a message as system |
| 531 | 534 | if (chat[j].extra?.type === system_message_types.NARRATOR) { |
| 532 | 535 | role = 'system'; |
| @@ -1637,8 +1640,6 @@ export function getChatCompletionModel(source = null) { | ||
| 1637 | 1640 | return oai_settings.groq_model; |
| 1638 | 1641 | case chat_completion_sources.ZEROONEAI: |
| 1639 | 1642 | return oai_settings.zerooneai_model; |
| 1640 | - case chat_completion_sources.BLOCKENTROPY: | |
| 1641 | - return oai_settings.blockentropy_model; | |
| 1642 | 1643 | case chat_completion_sources.NANOGPT: |
| 1643 | 1644 | return oai_settings.nanogpt_model; |
| 1644 | 1645 | case chat_completion_sources.DEEPSEEK: |
| @@ -1757,23 +1758,6 @@ function saveModelList(data) { | ||
| 1757 | 1758 | $('#model_01ai_select').val(oai_settings.zerooneai_model).trigger('change'); |
| 1758 | 1759 | } |
| 1759 | 1760 | |
| 1760 | - if (oai_settings.chat_completion_source == chat_completion_sources.BLOCKENTROPY) { | |
| 1761 | - $('#model_blockentropy_select').empty(); | |
| 1762 | - model_list.forEach((model) => { | |
| 1763 | - $('#model_blockentropy_select').append( | |
| 1764 | - $('<option>', { | |
| 1765 | - value: model.id, | |
| 1766 | - text: model.id, | |
| 1767 | - })); | |
| 1768 | - }); | |
| 1769 | - | |
| 1770 | - if (!oai_settings.blockentropy_model && model_list.length > 0) { | |
| 1771 | - oai_settings.blockentropy_model = model_list[0].id; | |
| 1772 | - } | |
| 1773 | - | |
| 1774 | - $('#model_blockentropy_select').val(oai_settings.blockentropy_model).trigger('change'); | |
| 1775 | - } | |
| 1776 | - | |
| 1777 | 1761 | if (oai_settings.chat_completion_source == chat_completion_sources.MISTRALAI) { |
| 1778 | 1762 | /** @type {HTMLSelectElement} */ |
| 1779 | 1763 | const mistralModelSelect = document.querySelector('#model_mistralai_select'); |
| @@ -3246,7 +3230,6 @@ function loadOpenAISettings(data, settings) { | ||
| 3246 | 3230 | oai_settings.groq_model = settings.groq_model ?? default_settings.groq_model; |
| 3247 | 3231 | oai_settings.nanogpt_model = settings.nanogpt_model ?? default_settings.nanogpt_model; |
| 3248 | 3232 | oai_settings.deepseek_model = settings.deepseek_model ?? default_settings.deepseek_model; |
| 3249 | - oai_settings.blockentropy_model = settings.blockentropy_model ?? default_settings.blockentropy_model; | |
| 3250 | 3233 | oai_settings.zerooneai_model = settings.zerooneai_model ?? default_settings.zerooneai_model; |
| 3251 | 3234 | oai_settings.custom_model = settings.custom_model ?? default_settings.custom_model; |
| 3252 | 3235 | oai_settings.custom_url = settings.custom_url ?? default_settings.custom_url; |
| @@ -3333,7 +3316,6 @@ function loadOpenAISettings(data, settings) { | ||
| 3333 | 3316 | $('#model_deepseek_select').val(oai_settings.deepseek_model); |
| 3334 | 3317 | $(`#model_deepseek_select option[value="${oai_settings.deepseek_model}"`).prop('selected', true); |
| 3335 | 3318 | $('#model_01ai_select').val(oai_settings.zerooneai_model); |
| 3336 | - $('#model_blockentropy_select').val(oai_settings.blockentropy_model); | |
| 3337 | 3319 | $('#custom_model_id').val(oai_settings.custom_model); |
| 3338 | 3320 | $('#custom_api_url_text').val(oai_settings.custom_url); |
| 3339 | 3321 | $('#openai_max_context').val(oai_settings.openai_max_context); |
| @@ -3613,7 +3595,6 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) { | ||
| 3613 | 3595 | perplexity_model: settings.perplexity_model, |
| 3614 | 3596 | groq_model: settings.groq_model, |
| 3615 | 3597 | zerooneai_model: settings.zerooneai_model, |
| 3616 | - blockentropy_model: settings.blockentropy_model, | |
| 3617 | 3598 | custom_model: settings.custom_model, |
| 3618 | 3599 | custom_url: settings.custom_url, |
| 3619 | 3600 | custom_include_body: settings.custom_include_body, |
| @@ -4322,12 +4303,6 @@ async function onModelChange() { | ||
| 4322 | 4303 | oai_settings.zerooneai_model = value; |
| 4323 | 4304 | } |
| 4324 | 4305 | |
| 4325 | - if (value && $(this).is('#model_blockentropy_select')) { | |
| 4326 | - console.log('Block Entropy model changed to', value); | |
| 4327 | - oai_settings.blockentropy_model = value; | |
| 4328 | - $('#blockentropy_model_id').val(value).trigger('input'); | |
| 4329 | - } | |
| 4330 | - | |
| 4331 | 4306 | if (value && $(this).is('#model_custom_select')) { |
| 4332 | 4307 | console.log('Custom model changed to', value); |
| 4333 | 4308 | oai_settings.custom_model = value; |
| @@ -4577,29 +4552,6 @@ async function onModelChange() { | ||
| 4577 | 4552 | oai_settings.temp_openai = Math.min(oai_max_temp, oai_settings.temp_openai); |
| 4578 | 4553 | $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); |
| 4579 | 4554 | } |
| 4580 | - if (oai_settings.chat_completion_source === chat_completion_sources.BLOCKENTROPY) { | |
| 4581 | - if (oai_settings.max_context_unlocked) { | |
| 4582 | - $('#openai_max_context').attr('max', unlocked_max); | |
| 4583 | - } | |
| 4584 | - else if (oai_settings.blockentropy_model.includes('llama3.1')) { | |
| 4585 | - $('#openai_max_context').attr('max', max_16k); | |
| 4586 | - } | |
| 4587 | - else if (oai_settings.blockentropy_model.includes('72b')) { | |
| 4588 | - $('#openai_max_context').attr('max', max_16k); | |
| 4589 | - } | |
| 4590 | - else if (oai_settings.blockentropy_model.includes('120b')) { | |
| 4591 | - $('#openai_max_context').attr('max', max_12k); | |
| 4592 | - } | |
| 4593 | - else { | |
| 4594 | - $('#openai_max_context').attr('max', max_8k); | |
| 4595 | - } | |
| 4596 | - | |
| 4597 | - oai_settings.openai_max_context = Math.min(oai_settings.openai_max_context, Number($('#openai_max_context').attr('max'))); | |
| 4598 | - $('#openai_max_context').val(oai_settings.openai_max_context).trigger('input'); | |
| 4599 | - | |
| 4600 | - oai_settings.temp_openai = Math.min(oai_max_temp, oai_settings.temp_openai); | |
| 4601 | - $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); | |
| 4602 | - } | |
| 4603 | 4555 | |
| 4604 | 4556 | if (oai_settings.chat_completion_source === chat_completion_sources.NANOGPT) { |
| 4605 | 4557 | if (oai_settings.max_context_unlocked) { |
| @@ -4866,18 +4818,6 @@ async function onConnectButtonClick(e) { | ||
| 4866 | 4818 | return; |
| 4867 | 4819 | } |
| 4868 | 4820 | } |
| 4869 | - if (oai_settings.chat_completion_source == chat_completion_sources.BLOCKENTROPY) { | |
| 4870 | - const api_key_blockentropy = String($('#api_key_blockentropy').val()).trim(); | |
| 4871 | - | |
| 4872 | - if (api_key_blockentropy.length) { | |
| 4873 | - await writeSecret(SECRET_KEYS.BLOCKENTROPY, api_key_blockentropy); | |
| 4874 | - } | |
| 4875 | - | |
| 4876 | - if (!secret_state[SECRET_KEYS.BLOCKENTROPY]) { | |
| 4877 | - console.log('No secret key saved for Block Entropy'); | |
| 4878 | - return; | |
| 4879 | - } | |
| 4880 | - } | |
| 4881 | 4821 | |
| 4882 | 4822 | startStatusLoading(); |
| 4883 | 4823 | saveSettingsDebounced(); |
| @@ -4932,9 +4872,6 @@ function toggleChatCompletionForms() { | ||
| 4932 | 4872 | else if (oai_settings.chat_completion_source == chat_completion_sources.CUSTOM) { |
| 4933 | 4873 | $('#model_custom_select').trigger('change'); |
| 4934 | 4874 | } |
| 4935 | - else if (oai_settings.chat_completion_source == chat_completion_sources.BLOCKENTROPY) { | |
| 4936 | - $('#model_blockentropy_select').trigger('change'); | |
| 4937 | - } | |
| 4938 | 4875 | else if (oai_settings.chat_completion_source == chat_completion_sources.DEEPSEEK) { |
| 4939 | 4876 | $('#model_deepseek_select').trigger('change'); |
| 4940 | 4877 | } |
| @@ -5687,7 +5624,6 @@ export function initOpenAI() { | ||
| 5687 | 5624 | $('#model_nanogpt_select').on('change', onModelChange); |
| 5688 | 5625 | $('#model_deepseek_select').on('change', onModelChange); |
| 5689 | 5626 | $('#model_01ai_select').on('change', onModelChange); |
| 5690 | - $('#model_blockentropy_select').on('change', onModelChange); | |
| 5691 | 5627 | $('#model_custom_select').on('change', onModelChange); |
| 5692 | 5628 | $('#settings_preset_openai').on('change', onSettingsPresetChange); |
| 5693 | 5629 | $('#new_oai_preset').on('click', onNewPresetClick); |
| @@ -34,7 +34,6 @@ export const SECRET_KEYS = { | ||
| 34 | 34 | ZEROONEAI: 'api_key_01ai', |
| 35 | 35 | HUGGINGFACE: 'api_key_huggingface', |
| 36 | 36 | STABILITY: 'api_key_stability', |
| 37 | - BLOCKENTROPY: 'api_key_blockentropy', | |
| 38 | 37 | CUSTOM_OPENAI_TTS: 'api_key_custom_openai_tts', |
| 39 | 38 | NANOGPT: 'api_key_nanogpt', |
| 40 | 39 | TAVILY: 'api_key_tavily', |
| @@ -74,7 +73,6 @@ const INPUT_MAP = { | ||
| 74 | 73 | [SECRET_KEYS.FEATHERLESS]: '#api_key_featherless', |
| 75 | 74 | [SECRET_KEYS.ZEROONEAI]: '#api_key_01ai', |
| 76 | 75 | [SECRET_KEYS.HUGGINGFACE]: '#api_key_huggingface', |
| 77 | - [SECRET_KEYS.BLOCKENTROPY]: '#api_key_blockentropy', | |
| 78 | 76 | [SECRET_KEYS.NANOGPT]: '#api_key_nanogpt', |
| 79 | 77 | [SECRET_KEYS.GENERIC]: '#api_key_generic', |
| 80 | 78 | [SECRET_KEYS.DEEPSEEK]: '#api_key_deepseek', |
| @@ -3936,7 +3936,6 @@ function getModelOptions(quiet) { | ||
| 3936 | 3936 | { id: 'model_groq_select', api: 'openai', type: chat_completion_sources.GROQ }, |
| 3937 | 3937 | { id: 'model_nanogpt_select', api: 'openai', type: chat_completion_sources.NANOGPT }, |
| 3938 | 3938 | { id: 'model_01ai_select', api: 'openai', type: chat_completion_sources.ZEROONEAI }, |
| 3939 | - { id: 'model_blockentropy_select', api: 'openai', type: chat_completion_sources.BLOCKENTROPY }, | |
| 3940 | 3939 | { id: 'model_deepseek_select', api: 'openai', type: chat_completion_sources.DEEPSEEK }, |
| 3941 | 3940 | { id: 'model_novel_select', api: 'novel', type: null }, |
| 3942 | 3941 | { id: 'horde_model', api: 'koboldhorde', type: null }, |
| @@ -83,6 +83,7 @@ import { convertCharacterBook, getWorldInfoPrompt, loadWorldInfo, reloadEditor, | ||
| 83 | 83 | import { ChatCompletionService, TextCompletionService } from './custom-request.js'; |
| 84 | 84 | import { ConnectionManagerRequestService } from './extensions/shared.js'; |
| 85 | 85 | import { updateReasoningUI, parseReasoningFromString } from './reasoning.js'; |
| 86 | +import { IGNORE_SYMBOL } from './constants.js'; | |
| 86 | 87 | |
| 87 | 88 | export function getContext() { |
| 88 | 89 | return { |
| @@ -225,6 +226,9 @@ export function getContext() { | ||
| 225 | 226 | parseReasoningFromString, |
| 226 | 227 | unshallowCharacter, |
| 227 | 228 | unshallowGroupMembers, |
| 229 | + symbols: { | |
| 230 | + ignore: IGNORE_SYMBOL, | |
| 231 | + }, | |
| 228 | 232 | }; |
| 229 | 233 | } |
| 230 | 234 | |
| @@ -1,4 +1,4 @@ | ||
| 1 | 1 | <div id="WIEntryHeaderTitlesPC" class="flex-container wide100p spaceBetween justifyCenter textAlignCenter" style="padding:0 47.5em0em;"> |
| 2 | 2 | <small class="flex1" data-i18n="Title/Memo">Title/Memo</small> |
| 3 | 3 | <small style="width: calc(3.5em + 10px)" data-i18n="Strategy">Strategy</small> |
| 4 | 4 | <small style="width: calc(3.5em + 20px)" data-i18n="Position">Position</small> |
| @@ -729,15 +729,6 @@ export function getTokenizerModel() { | ||
| 729 | 729 | return yiTokenizer; |
| 730 | 730 | } |
| 731 | 731 | |
| 732 | - if (oai_settings.chat_completion_source === chat_completion_sources.BLOCKENTROPY) { | |
| 733 | - if (oai_settings.blockentropy_model.includes('llama3')) { | |
| 734 | - return llama3Tokenizer; | |
| 735 | - } | |
| 736 | - if (oai_settings.blockentropy_model.includes('miqu') || oai_settings.blockentropy_model.includes('mixtral')) { | |
| 737 | - return mistralTokenizer; | |
| 738 | - } | |
| 739 | - } | |
| 740 | - | |
| 741 | 732 | // Default to Turbo 3.5 |
| 742 | 733 | return turboTokenizer; |
| 743 | 734 | } |
| @@ -2208,7 +2208,7 @@ function verifyWorldInfoSearchSortRule() { | ||
| 2208 | 2208 | * Use `originalWIDataKeyMap` to find the correct value to be set. |
| 2209 | 2209 | * |
| 2210 | 2210 | * @param {object} data - The data object containing the original data entries. |
| 2211 | 2211 | * @param {stringnumber} uid - The unique identifier of the data entry. |
| 2212 | 2212 | * @param {string} key - The key of the value to be set. |
| 2213 | 2213 | * @param {any} value - The value to be set. |
| 2214 | 2214 | */ |
| @@ -2232,7 +2232,9 @@ export function setWIOriginalDataValue(data, uid, key, value) { | ||
| 2232 | 2232 | */ |
| 2233 | 2233 | export function deleteWIOriginalDataValue(data, uid) { |
| 2234 | 2234 | if (data.originalData && Array.isArray(data.originalData.entries)) { |
| 2235 | - const originalIndex = data.originalData.entries.findIndex(x => x.uid === uid); | |
| 2235 | + // Non-strict equality is used here to allow for both string and number comparisons | |
| 2236 | + // @eslint-disable-next-line eqeqeq | |
| 2237 | + const originalIndex = data.originalData.entries.findIndex(x => x.uid == uid); | |
| 2236 | 2238 | |
| 2237 | 2239 | if (originalIndex >= 0) { |
| 2238 | 2240 | data.originalData.entries.splice(originalIndex, 1); |
| @@ -2680,8 +2682,10 @@ export async function getWorldEntry(name, data, entry) { | ||
| 2680 | 2682 | $(counter).text(numberOfTokens); |
| 2681 | 2683 | }, debounce_timeout.relaxed); |
| 2682 | 2684 | |
| 2685 | + const contentInputId = `world_entry_content_${entry.uid}`; | |
| 2683 | 2686 | const contentInput = template.find('textarea[name="content"]'); |
| 2684 | 2687 | contentInput.data('uid', entry.uid); |
| 2688 | + contentInput.attr('id', contentInputId); | |
| 2685 | 2689 | contentInput.on('input', async function (_, { skipCount } = {}) { |
| 2686 | 2690 | const uid = $(this).data('uid'); |
| 2687 | 2691 | const value = $(this).val(); |
| @@ -2698,7 +2702,9 @@ export async function getWorldEntry(name, data, entry) { | ||
| 2698 | 2702 | countTokensDebounced(counter, value); |
| 2699 | 2703 | }); |
| 2700 | 2704 | contentInput.val(entry.content).trigger('input', { skipCount: true }); |
| 2701 | - //initScrollHeight(contentInput); | |
| 2705 | + | |
| 2706 | + const contentExpandButton = template.find('.editor_maximize'); | |
| 2707 | + contentExpandButton.attr('data-for', contentInputId); | |
| 2702 | 2708 | |
| 2703 | 2709 | template.find('.inline-drawer-toggle').on('click', function () { |
| 2704 | 2710 | if (counter.data('first-run')) { |
| @@ -3139,6 +3145,84 @@ export async function getWorldEntry(name, data, entry) { | ||
| 3139 | 3145 | updateEditor(navigation_option.previous); |
| 3140 | 3146 | }); |
| 3141 | 3147 | |
| 3148 | + // move button | |
| 3149 | + const moveButton = template.find('.move_entry_button'); | |
| 3150 | + moveButton.attr('data-uid', entry.uid); | |
| 3151 | + moveButton.attr('data-current-world', name); | |
| 3152 | + moveButton.on('click', async function (e) { | |
| 3153 | + e.stopPropagation(); | |
| 3154 | + const sourceUid = $(this).attr('data-uid'); | |
| 3155 | + const sourceWorld = $(this).attr('data-current-world'); | |
| 3156 | + const sourceWorldInfo = await loadWorldInfo(sourceWorld); | |
| 3157 | + if (!sourceWorldInfo) { | |
| 3158 | + return; | |
| 3159 | + } | |
| 3160 | + const sourceName = sourceWorldInfo.entries[sourceUid]?.comment; | |
| 3161 | + if (sourceName === undefined) { | |
| 3162 | + return; | |
| 3163 | + } | |
| 3164 | + | |
| 3165 | + const select = document.createElement('select'); | |
| 3166 | + select.id = 'move_entry_target_select'; | |
| 3167 | + select.classList.add('text_pole', 'wide100p', 'marginTop10'); | |
| 3168 | + | |
| 3169 | + const defaultOption = document.createElement('option'); | |
| 3170 | + defaultOption.value = ''; | |
| 3171 | + defaultOption.textContent = `-- ${t`Select Target Lorebook`} --`; | |
| 3172 | + select.appendChild(defaultOption); | |
| 3173 | + | |
| 3174 | + let selectableWorldCount = 0; | |
| 3175 | + world_names.forEach(worldName => { | |
| 3176 | + if (worldName !== sourceWorld) { // Exclude current world | |
| 3177 | + const option = document.createElement('option'); | |
| 3178 | + option.value = world_names.indexOf(worldName).toString(); | |
| 3179 | + option.textContent = worldName; | |
| 3180 | + select.appendChild(option); | |
| 3181 | + selectableWorldCount++; | |
| 3182 | + } | |
| 3183 | + }); | |
| 3184 | + | |
| 3185 | + if (selectableWorldCount === 0) { | |
| 3186 | + toastr.warning(t`There are no other lorebooks to move to.`); | |
| 3187 | + return; | |
| 3188 | + } | |
| 3189 | + | |
| 3190 | + // Create wrapper div | |
| 3191 | + const wrapper = document.createElement('div'); | |
| 3192 | + wrapper.textContent = t`Move "${sourceName}" to:`; | |
| 3193 | + | |
| 3194 | + // Create container and append elements | |
| 3195 | + const container = document.createElement('div'); | |
| 3196 | + container.appendChild(wrapper); | |
| 3197 | + container.appendChild(select); | |
| 3198 | + | |
| 3199 | + let selectedWorldIndex = -1; | |
| 3200 | + select.addEventListener('change', function() { | |
| 3201 | + selectedWorldIndex = this.value === '' ? -1 : Number(this.value); | |
| 3202 | + }); | |
| 3203 | + | |
| 3204 | + const popupConfirm = await callGenericPopup(container, POPUP_TYPE.CONFIRM, '', { | |
| 3205 | + okButton: t`Move`, | |
| 3206 | + cancelButton: t`Cancel`, | |
| 3207 | + }); | |
| 3208 | + if (!popupConfirm) { | |
| 3209 | + return; | |
| 3210 | + } | |
| 3211 | + | |
| 3212 | + if (selectedWorldIndex === -1) { | |
| 3213 | + return; | |
| 3214 | + } | |
| 3215 | + | |
| 3216 | + const selectedValue = world_names[selectedWorldIndex]; | |
| 3217 | + | |
| 3218 | + if (!selectedValue) { | |
| 3219 | + toastr.warning(t`Please select a target lorebook.`); | |
| 3220 | + return; | |
| 3221 | + } | |
| 3222 | + | |
| 3223 | + await moveWorldInfoEntry(sourceWorld, selectedValue, sourceUid); | |
| 3224 | + }); | |
| 3225 | + | |
| 3142 | 3226 | // scan depth |
| 3143 | 3227 | const scanDepthInput = template.find('input[name="scanDepth"]'); |
| 3144 | 3228 | scanDepthInput.data('uid', entry.uid); |
| @@ -5267,3 +5351,99 @@ jQuery(() => { | ||
| 5267 | 5351 | }); |
| 5268 | 5352 | }); |
| 5269 | 5353 | }); |
| 5354 | + | |
| 5355 | +/** | |
| 5356 | + * Moves a World Info entry from a source lorebook to a target lorebook. | |
| 5357 | + * | |
| 5358 | + * @param {string} sourceName - The name of the source lorebook file. | |
| 5359 | + * @param {string} targetName - The name of the target lorebook file. | |
| 5360 | + * @param {string|number} uid - The UID of the entry to move from the source lorebook. | |
| 5361 | + * @returns {Promise<boolean>} True if the move was successful, false otherwise. | |
| 5362 | + */ | |
| 5363 | +export async function moveWorldInfoEntry(sourceName, targetName, uid) { | |
| 5364 | + if (sourceName === targetName) { | |
| 5365 | + return false; | |
| 5366 | + } | |
| 5367 | + | |
| 5368 | + if (!world_names.includes(sourceName)) { | |
| 5369 | + toastr.error(t`Source lorebook '${sourceName}' not found.`); | |
| 5370 | + console.error(`[WI Move] Source lorebook '${sourceName}' does not exist.`); | |
| 5371 | + return false; | |
| 5372 | + } | |
| 5373 | + | |
| 5374 | + if (!world_names.includes(targetName)) { | |
| 5375 | + toastr.error(t`Target lorebook '${targetName}' not found.`); | |
| 5376 | + console.error(`[WI Move] Target lorebook '${targetName}' does not exist.`); | |
| 5377 | + return false; | |
| 5378 | + } | |
| 5379 | + | |
| 5380 | + const entryUidString = String(uid); | |
| 5381 | + | |
| 5382 | + try { | |
| 5383 | + const sourceData = await loadWorldInfo(sourceName); | |
| 5384 | + const targetData = await loadWorldInfo(targetName); | |
| 5385 | + | |
| 5386 | + if (!sourceData || !sourceData.entries) { | |
| 5387 | + toastr.error(t`Failed to load data for source lorebook '${sourceName}'.`); | |
| 5388 | + console.error(`[WI Move] Could not load source data for '${sourceName}'.`); | |
| 5389 | + return false; | |
| 5390 | + } | |
| 5391 | + if (!targetData || !targetData.entries) { | |
| 5392 | + toastr.error(t`Failed to load data for target lorebook '${targetName}'.`); | |
| 5393 | + console.error(`[WI Move] Could not load target data for '${targetName}'.`); | |
| 5394 | + return false; | |
| 5395 | + } | |
| 5396 | + | |
| 5397 | + if (!sourceData.entries[entryUidString]) { | |
| 5398 | + toastr.error(t`Entry not found in source lorebook '${sourceName}'.`); | |
| 5399 | + console.error(`[WI Move] Entry UID ${entryUidString} not found in '${sourceName}'.`); | |
| 5400 | + return false; | |
| 5401 | + } | |
| 5402 | + | |
| 5403 | + const entryToMove = structuredClone(sourceData.entries[entryUidString]); | |
| 5404 | + | |
| 5405 | + | |
| 5406 | + const newUid = getFreeWorldEntryUid(targetData); | |
| 5407 | + if (newUid === null) { | |
| 5408 | + console.error(`[WI Move] Failed to get a free UID in '${targetName}'.`); | |
| 5409 | + return false; | |
| 5410 | + } | |
| 5411 | + | |
| 5412 | + entryToMove.uid = newUid; | |
| 5413 | + // Place the entry at the end of the target lorebook | |
| 5414 | + const maxDisplayIndex = Object.values(targetData.entries).reduce((max, entry) => Math.max(max, entry.displayIndex ?? -1), -1); | |
| 5415 | + entryToMove.displayIndex = maxDisplayIndex + 1; | |
| 5416 | + | |
| 5417 | + targetData.entries[newUid] = entryToMove; | |
| 5418 | + | |
| 5419 | + delete sourceData.entries[entryUidString]; | |
| 5420 | + // Remove from originalData if it exists | |
| 5421 | + deleteWIOriginalDataValue(sourceData, entryUidString); | |
| 5422 | + // TODO: setWIOriginalDataValue | |
| 5423 | + console.debug(`[WI Move] Removed entry UID ${entryUidString} from source '${sourceName}'.`); | |
| 5424 | + | |
| 5425 | + | |
| 5426 | + await saveWorldInfo(targetName, targetData, true); | |
| 5427 | + console.debug(`[WI Move] Saved target lorebook '${targetName}'.`); | |
| 5428 | + await saveWorldInfo(sourceName, sourceData, true); | |
| 5429 | + console.debug(`[WI Move] Saved source lorebook '${sourceName}'.`); | |
| 5430 | + | |
| 5431 | + | |
| 5432 | + console.log(`[WI Move] ${entryToMove.comment} moved successfully to '${targetName}'.`); | |
| 5433 | + | |
| 5434 | + // Check if the currently viewed book in the editor is the source or target and reload it | |
| 5435 | + const currentEditorBookIndex = Number($('#world_editor_select').val()); | |
| 5436 | + if (!isNaN(currentEditorBookIndex)) { | |
| 5437 | + const currentEditorBookName = world_names[currentEditorBookIndex]; | |
| 5438 | + if (currentEditorBookName === sourceName || currentEditorBookName === targetName) { | |
| 5439 | + reloadEditor(currentEditorBookName); | |
| 5440 | + } | |
| 5441 | + } | |
| 5442 | + | |
| 5443 | + return true; | |
| 5444 | + } catch (error) { | |
| 5445 | + toastr.error(t`An unexpected error occurred while moving the entry: ${error.message}`); | |
| 5446 | + console.error('[WI Move] Unexpected error:', error); | |
| 5447 | + return false; | |
| 5448 | + } | |
| 5449 | +} | |
| @@ -174,7 +174,6 @@ export const CHAT_COMPLETION_SOURCES = { | ||
| 174 | 174 | PERPLEXITY: 'perplexity', |
| 175 | 175 | GROQ: 'groq', |
| 176 | 176 | ZEROONEAI: '01ai', |
| 177 | - BLOCKENTROPY: 'blockentropy', | |
| 178 | 177 | NANOGPT: 'nanogpt', |
| 179 | 178 | DEEPSEEK: 'deepseek', |
| 180 | 179 | }; |
| @@ -50,7 +50,6 @@ const API_PERPLEXITY = 'https://api.perplexity.ai'; | ||
| 50 | 50 | const API_GROQ = 'https://api.groq.com/openai/v1'; |
| 51 | 51 | const API_MAKERSUITE = 'https://generativelanguage.googleapis.com'; |
| 52 | 52 | const API_01AI = 'https://api.lingyiwanwu.com/v1'; |
| 53 | -const API_BLOCKENTROPY = 'https://api.blockentropy.ai/v1'; | |
| 54 | 53 | const API_AI21 = 'https://api.ai21.com/studio/v1'; |
| 55 | 54 | const API_NANOGPT = 'https://nano-gpt.com/api/v1'; |
| 56 | 55 | const API_DEEPSEEK = 'https://api.deepseek.com/beta'; |
| @@ -865,10 +864,6 @@ router.post('/status', async function (request, response_getstatus_openai) { | ||
| 865 | 864 | api_url = API_01AI; |
| 866 | 865 | api_key_openai = readSecret(request.user.directories, SECRET_KEYS.ZEROONEAI); |
| 867 | 866 | headers = {}; |
| 868 | - } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.BLOCKENTROPY) { | |
| 869 | - api_url = API_BLOCKENTROPY; | |
| 870 | - api_key_openai = readSecret(request.user.directories, SECRET_KEYS.BLOCKENTROPY); | |
| 871 | - headers = {}; | |
| 872 | 867 | } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.NANOGPT) { |
| 873 | 868 | api_url = API_NANOGPT; |
| 874 | 869 | api_key_openai = readSecret(request.user.directories, SECRET_KEYS.NANOGPT); |
| @@ -1155,11 +1150,6 @@ router.post('/generate', function (request, response) { | ||
| 1155 | 1150 | apiKey = readSecret(request.user.directories, SECRET_KEYS.ZEROONEAI); |
| 1156 | 1151 | headers = {}; |
| 1157 | 1152 | bodyParams = {}; |
| 1158 | - } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.BLOCKENTROPY) { | |
| 1159 | - apiUrl = API_BLOCKENTROPY; | |
| 1160 | - apiKey = readSecret(request.user.directories, SECRET_KEYS.BLOCKENTROPY); | |
| 1161 | - headers = {}; | |
| 1162 | - bodyParams = {}; | |
| 1163 | 1153 | } else { |
| 1164 | 1154 | console.warn('This chat completion source is not supported yet.'); |
| 1165 | 1155 | return response.status(400).send({ error: true }); |
| @@ -44,7 +44,6 @@ export const SECRET_KEYS = { | ||
| 44 | 44 | ZEROONEAI: 'api_key_01ai', |
| 45 | 45 | HUGGINGFACE: 'api_key_huggingface', |
| 46 | 46 | STABILITY: 'api_key_stability', |
| 47 | - BLOCKENTROPY: 'api_key_blockentropy', | |
| 48 | 47 | CUSTOM_OPENAI_TTS: 'api_key_custom_openai_tts', |
| 49 | 48 | TAVILY: 'api_key_tavily', |
| 50 | 49 | NANOGPT: 'api_key_nanogpt', |
| @@ -907,89 +907,6 @@ stability.post('/generate', async (request, response) => { | ||
| 907 | 907 | } |
| 908 | 908 | }); |
| 909 | 909 | |
| 910 | -const blockentropy = express.Router(); | |
| 911 | - | |
| 912 | -blockentropy.post('/models', async (request, response) => { | |
| 913 | - try { | |
| 914 | - const key = readSecret(request.user.directories, SECRET_KEYS.BLOCKENTROPY); | |
| 915 | - | |
| 916 | - if (!key) { | |
| 917 | - console.warn('Block Entropy key not found.'); | |
| 918 | - return response.sendStatus(400); | |
| 919 | - } | |
| 920 | - | |
| 921 | - const modelsResponse = await fetch('https://api.blockentropy.ai/sdapi/v1/sd-models', { | |
| 922 | - method: 'GET', | |
| 923 | - headers: { | |
| 924 | - 'Authorization': `Bearer ${key}`, | |
| 925 | - }, | |
| 926 | - }); | |
| 927 | - | |
| 928 | - if (!modelsResponse.ok) { | |
| 929 | - console.warn('Block Entropy returned an error.'); | |
| 930 | - return response.sendStatus(500); | |
| 931 | - } | |
| 932 | - | |
| 933 | - const data = await modelsResponse.json(); | |
| 934 | - | |
| 935 | - if (!Array.isArray(data)) { | |
| 936 | - console.warn('Block Entropy returned invalid data.'); | |
| 937 | - return response.sendStatus(500); | |
| 938 | - } | |
| 939 | - const models = data.map(x => ({ value: x.name, text: x.name })); | |
| 940 | - return response.send(models); | |
| 941 | - | |
| 942 | - } catch (error) { | |
| 943 | - console.error(error); | |
| 944 | - return response.sendStatus(500); | |
| 945 | - } | |
| 946 | -}); | |
| 947 | - | |
| 948 | -blockentropy.post('/generate', async (request, response) => { | |
| 949 | - try { | |
| 950 | - const key = readSecret(request.user.directories, SECRET_KEYS.BLOCKENTROPY); | |
| 951 | - | |
| 952 | - if (!key) { | |
| 953 | - console.warn('Block Entropy key not found.'); | |
| 954 | - return response.sendStatus(400); | |
| 955 | - } | |
| 956 | - | |
| 957 | - console.debug('Block Entropy request:', request.body); | |
| 958 | - | |
| 959 | - const result = await fetch('https://api.blockentropy.ai/sdapi/v1/txt2img', { | |
| 960 | - method: 'POST', | |
| 961 | - body: JSON.stringify({ | |
| 962 | - prompt: request.body.prompt, | |
| 963 | - negative_prompt: request.body.negative_prompt, | |
| 964 | - model: request.body.model, | |
| 965 | - steps: request.body.steps, | |
| 966 | - width: request.body.width, | |
| 967 | - height: request.body.height, | |
| 968 | - // Random seed if negative. | |
| 969 | - seed: request.body.seed >= 0 ? request.body.seed : Math.floor(Math.random() * 10_000_000), | |
| 970 | - }), | |
| 971 | - headers: { | |
| 972 | - 'Content-Type': 'application/json', | |
| 973 | - 'Authorization': `Bearer ${key}`, | |
| 974 | - }, | |
| 975 | - }); | |
| 976 | - | |
| 977 | - if (!result.ok) { | |
| 978 | - console.warn('Block Entropy returned an error.'); | |
| 979 | - return response.sendStatus(500); | |
| 980 | - } | |
| 981 | - | |
| 982 | - const data = await result.json(); | |
| 983 | - console.debug('Block Entropy response:', data); | |
| 984 | - | |
| 985 | - return response.send(data); | |
| 986 | - } catch (error) { | |
| 987 | - console.error(error); | |
| 988 | - return response.sendStatus(500); | |
| 989 | - } | |
| 990 | -}); | |
| 991 | - | |
| 992 | - | |
| 993 | 910 | const huggingface = express.Router(); |
| 994 | 911 | |
| 995 | 912 | huggingface.post('/generate', async (request, response) => { |
| @@ -1358,7 +1275,6 @@ router.use('/together', together); | ||
| 1358 | 1275 | router.use('/drawthings', drawthings); |
| 1359 | 1276 | router.use('/pollinations', pollinations); |
| 1360 | 1277 | router.use('/stability', stability); |
| 1361 | -router.use('/blockentropy', blockentropy); | |
| 1362 | 1278 | router.use('/huggingface', huggingface); |
| 1363 | 1279 | router.use('/nanogpt', nanogpt); |
| 1364 | 1280 | router.use('/bfl', bfl); |