Merge pull request #3102 from ceruleandeep/fix/sdInteractiveYour Fix "send a photo of yourself" etc in SD interactive mode
Signed| @@ -1,37 +1,62 @@ | |||
| 1 | import { Popper } from '../../../lib.js'; | 1 | import { Popper } from '../../../lib.js'; |
| 2 | import { | 2 | import { |
| 3 | saveSettingsDebounced, | 3 | animation_duration, |
| 4 | systemUserName, | 4 | appendMediaToMessage, |
| 5 | getRequestHeaders, | ||
| 6 | event_types, | 5 | event_types, |
| 7 | eventSource, | 6 | eventSource, |
| 7 | formatCharacterAvatar, | ||
| 8 | generateQuietPrompt, | 8 | generateQuietPrompt, |
| 9 | this_chid, | 9 | getCharacterAvatar, |
| 10 | getCurrentChatId, | 10 | getCurrentChatId, |
| 11 | animation_duration, | 11 | getRequestHeaders, |
| 12 | appendMediaToMessage, | ||
| 13 | getUserAvatar, | 12 | getUserAvatar, |
| 14 | user_avatar, | 13 | saveSettingsDebounced, |
| 15 | getCharacterAvatar, | ||
| 16 | formatCharacterAvatar, | ||
| 17 | substituteParams, | 14 | substituteParams, |
| 18 | substituteParamsExtended, | 15 | substituteParamsExtended, |
| 16 | systemUserName, | ||
| 17 | this_chid, | ||
| 18 | user_avatar, | ||
| 19 | } from '../../../script.js'; | 19 | } from '../../../script.js'; |
| 20 | import { getApiUrl, getContext, extension_settings, doExtrasFetch, modules, renderExtensionTemplateAsync, writeExtensionField } from '../../extensions.js'; | 20 | import { |
| 21 | doExtrasFetch, | ||
| 22 | extension_settings, | ||
| 23 | getApiUrl, | ||
| 24 | getContext, | ||
| 25 | modules, | ||
| 26 | renderExtensionTemplateAsync, | ||
| 27 | writeExtensionField, | ||
| 28 | } from '../../extensions.js'; | ||
| 21 | import { selected_group } from '../../group-chats.js'; | 29 | import { selected_group } from '../../group-chats.js'; |
| 22 | import { stringFormat, initScrollHeight, resetScrollHeight, getCharaFilename, saveBase64AsFile, getBase64Async, delay, isTrueBoolean, debounce, isFalseBoolean, deepMerge } from '../../utils.js'; | 30 | import { |
| 31 | debounce, | ||
| 32 | deepMerge, | ||
| 33 | delay, | ||
| 34 | getBase64Async, | ||
| 35 | getCharaFilename, | ||
| 36 | initScrollHeight, | ||
| 37 | isFalseBoolean, | ||
| 38 | isTrueBoolean, | ||
| 39 | resetScrollHeight, | ||
| 40 | saveBase64AsFile, | ||
| 41 | stringFormat, | ||
| 42 | } from '../../utils.js'; | ||
| 23 | import { getMessageTimeStamp, humanizedDateTime } from '../../RossAscends-mods.js'; | 43 | import { getMessageTimeStamp, humanizedDateTime } from '../../RossAscends-mods.js'; |
| 24 | import { SECRET_KEYS, secret_state, writeSecret } from '../../secrets.js'; | 44 | import { SECRET_KEYS, secret_state, writeSecret } from '../../secrets.js'; |
| 25 | import { getNovelUnlimitedImageGeneration, getNovelAnlas, loadNovelSubscriptionData } from '../../nai-settings.js'; | 45 | import { getNovelAnlas, getNovelUnlimitedImageGeneration, loadNovelSubscriptionData } from '../../nai-settings.js'; |
| 26 | import { getMultimodalCaption } from '../shared.js'; | 46 | import { getMultimodalCaption } from '../shared.js'; |
| 27 | import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js'; | 47 | import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js'; |
| 28 | import { SlashCommand } from '../../slash-commands/SlashCommand.js'; | 48 | import { SlashCommand } from '../../slash-commands/SlashCommand.js'; |
| 29 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js'; | 49 | import { |
| 50 | ARGUMENT_TYPE, | ||
| 51 | SlashCommandArgument, | ||
| 52 | SlashCommandNamedArgument, | ||
| 53 | } from '../../slash-commands/SlashCommandArgument.js'; | ||
| 30 | import { debounce_timeout } from '../../constants.js'; | 54 | import { debounce_timeout } from '../../constants.js'; |
| 31 | import { SlashCommandEnumValue } from '../../slash-commands/SlashCommandEnumValue.js'; | 55 | import { SlashCommandEnumValue } from '../../slash-commands/SlashCommandEnumValue.js'; |
| 32 | import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from '../../popup.js'; | 56 | import { callGenericPopup, Popup, POPUP_RESULT, POPUP_TYPE } from '../../popup.js'; |
| 33 | import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js'; | 57 | import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 34 | import { ToolManager } from '../../tool-calling.js'; | 58 | import { ToolManager } from '../../tool-calling.js'; |
| 59 | |||
| 35 | export { MODULE_NAME }; | 60 | export { MODULE_NAME }; |
| 36 | 61 | ||
| 37 | const MODULE_NAME = 'sd'; | 62 | const MODULE_NAME = 'sd'; |
| @@ -118,13 +143,13 @@ const triggerWords = { | |||
| 118 | }; | 143 | }; |
| 119 | 144 | ||
| 120 | const messageTrigger = { | 145 | const messageTrigger = { |
| 121 | activationRegex: /\b(send|mail|imagine|generate|make|create|draw|paint|render|show)\b.{0,10}\b(pic|picture|image|drawing|painting|photo|photograph)\b(?:\s+of)?(?:\s+(?:a|an|the|this|that|those|your)?)?(.+)/i, | 146 | activationRegex: /\b(send|mail|imagine|generate|make|create|draw|paint|render|show)\b.{0,10}\b(pic|picture|image|drawing|painting|photo|photograph)\b(?:\s+of)?(?:\s+(?:a|an|the|this|that|those|your)?\s+)?(.+)/i, |
| 122 | specialCases: { | 147 | specialCases: { |
| 123 | [generationMode.CHARACTER]: ['you', 'yourself'], | 148 | [generationMode.CHARACTER]: ['you', 'yourself'], |
| 124 | [generationMode.USER]: ['me', 'myself'], | 149 | [generationMode.USER]: ['me', 'myself'], |
| 125 | [generationMode.SCENARIO]: ['story', 'scenario', 'whole story'], | 150 | [generationMode.SCENARIO]: ['story', 'scenario', 'whole story'], |
| 126 | [generationMode.NOW]: ['last message'], | 151 | [generationMode.NOW]: ['last message'], |
| 127 | [generationMode.FACE]: ['your face', 'your portrait', 'your selfie'], | 152 | [generationMode.FACE]: ['face', 'portrait', 'selfie'], |
| 128 | [generationMode.BACKGROUND]: ['background', 'scene background', 'scene', 'scenery', 'surroundings', 'environment'], | 153 | [generationMode.BACKGROUND]: ['background', 'scene background', 'scene', 'scenery', 'surroundings', 'environment'], |
| 129 | }, | 154 | }, |
| 130 | }; | 155 | }; |
| @@ -343,7 +368,7 @@ function processTriggers(chat, _, abort) { | |||
| 343 | return; | 368 | return; |
| 344 | } | 369 | } |
| 345 | 370 | ||
| 346 | console.log(`SD: Triggered by "${message}", detected subject: ${subject}"`); | 371 | console.log(`SD: Triggered by "${message}", detected subject: "${subject}"`); |
| 347 | 372 | ||
| 348 | outer: for (const [specialMode, triggers] of Object.entries(messageTrigger.specialCases)) { | 373 | outer: for (const [specialMode, triggers] of Object.entries(messageTrigger.specialCases)) { |
| 349 | for (const trigger of triggers) { | 374 | for (const trigger of triggers) { |
| @@ -359,7 +384,6 @@ function processTriggers(chat, _, abort) { | |||
| 359 | setTimeout(() => generatePicture(initiators.interactive, {}, subject, message), 1); | 384 | setTimeout(() => generatePicture(initiators.interactive, {}, subject, message), 1); |
| 360 | } catch { | 385 | } catch { |
| 361 | console.log('SD: Failed to process triggers.'); | 386 | console.log('SD: Failed to process triggers.'); |
| 362 | return; | ||
| 363 | } | 387 | } |
| 364 | } | 388 | } |
| 365 | 389 | ||
| @@ -685,7 +709,7 @@ async function refinePrompt(prompt, isNegative) { | |||
| 685 | return prompt; | 709 | return prompt; |
| 686 | } | 710 | } |
| 687 | 711 | ||
| 688 | function onChatChanged() { | 712 | async function onChatChanged() { |
| 689 | if (this_chid === undefined || selected_group) { | 713 | if (this_chid === undefined || selected_group) { |
| 690 | $('#sd_character_prompt_block').hide(); | 714 | $('#sd_character_prompt_block').hide(); |
| 691 | return; | 715 | return; |
| @@ -713,7 +737,7 @@ function onChatChanged() { | |||
| 713 | $('#sd_character_prompt').val(characterPrompt); | 737 | $('#sd_character_prompt').val(characterPrompt); |
| 714 | $('#sd_character_negative_prompt').val(negativePrompt); | 738 | $('#sd_character_negative_prompt').val(negativePrompt); |
| 715 | $('#sd_character_prompt_share').prop('checked', hasSharedData); | 739 | $('#sd_character_prompt_share').prop('checked', hasSharedData); |
| 716 | adjustElementScrollHeight(); | 740 | await adjustElementScrollHeight(); |
| 717 | } | 741 | } |
| 718 | 742 | ||
| 719 | async function adjustElementScrollHeight() { | 743 | async function adjustElementScrollHeight() { |
| @@ -1285,8 +1309,7 @@ async function getAutoRemoteModel() { | |||
| 1285 | throw new Error('SD WebUI returned an error.'); | 1309 | throw new Error('SD WebUI returned an error.'); |
| 1286 | } | 1310 | } |
| 1287 | 1311 | ||
| 1288 | const data = await result.text(); | 1312 | return await result.text(); |
| 1289 | return data; | ||
| 1290 | } catch (error) { | 1313 | } catch (error) { |
| 1291 | console.error(error); | 1314 | console.error(error); |
| 1292 | return null; | 1315 | return null; |
| @@ -1305,9 +1328,7 @@ async function getDrawthingsRemoteModel() { | |||
| 1305 | throw new Error('SD DrawThings API returned an error.'); | 1328 | throw new Error('SD DrawThings API returned an error.'); |
| 1306 | } | 1329 | } |
| 1307 | 1330 | ||
| 1308 | const data = await result.text(); | 1331 | return await result.text(); |
| 1309 | |||
| 1310 | return data; | ||
| 1311 | } catch (error) { | 1332 | } catch (error) { |
| 1312 | console.error(error); | 1333 | console.error(error); |
| 1313 | return null; | 1334 | return null; |
| @@ -1330,8 +1351,7 @@ async function getAutoRemoteUpscalers() { | |||
| 1330 | throw new Error('SD WebUI returned an error.'); | 1351 | throw new Error('SD WebUI returned an error.'); |
| 1331 | } | 1352 | } |
| 1332 | 1353 | ||
| 1333 | const data = await result.json(); | 1354 | return await result.json(); |
| 1334 | return data; | ||
| 1335 | } catch (error) { | 1355 | } catch (error) { |
| 1336 | console.error(error); | 1356 | console.error(error); |
| 1337 | return [extension_settings.sd.hr_upscaler]; | 1357 | return [extension_settings.sd.hr_upscaler]; |
| @@ -1350,8 +1370,7 @@ async function getAutoRemoteSchedulers() { | |||
| 1350 | throw new Error('SD WebUI returned an error.'); | 1370 | throw new Error('SD WebUI returned an error.'); |
| 1351 | } | 1371 | } |
| 1352 | 1372 | ||
| 1353 | const data = await result.json(); | 1373 | return await result.json(); |
| 1354 | return data; | ||
| 1355 | } catch (error) { | 1374 | } catch (error) { |
| 1356 | console.error(error); | 1375 | console.error(error); |
| 1357 | return ['N/A']; | 1376 | return ['N/A']; |
| @@ -1370,8 +1389,7 @@ async function getVladRemoteUpscalers() { | |||
| 1370 | throw new Error('SD.Next returned an error.'); | 1389 | throw new Error('SD.Next returned an error.'); |
| 1371 | } | 1390 | } |
| 1372 | 1391 | ||
| 1373 | const data = await result.json(); | 1392 | return await result.json(); |
| 1374 | return data; | ||
| 1375 | } catch (error) { | 1393 | } catch (error) { |
| 1376 | console.error(error); | 1394 | console.error(error); |
| 1377 | return [extension_settings.sd.hr_upscaler]; | 1395 | return [extension_settings.sd.hr_upscaler]; |
| @@ -1504,8 +1522,7 @@ async function loadHordeSamplers() { | |||
| 1504 | }); | 1522 | }); |
| 1505 | 1523 | ||
| 1506 | if (result.ok) { | 1524 | if (result.ok) { |
| 1507 | const data = await result.json(); | 1525 | return await result.json(); |
| 1508 | return data; | ||
| 1509 | } | 1526 | } |
| 1510 | 1527 | ||
| 1511 | return []; | 1528 | return []; |
| @@ -1544,8 +1561,7 @@ async function loadAutoSamplers() { | |||
| 1544 | throw new Error('SD WebUI returned an error.'); | 1561 | throw new Error('SD WebUI returned an error.'); |
| 1545 | } | 1562 | } |
| 1546 | 1563 | ||
| 1547 | const data = await result.json(); | 1564 | return await result.json(); |
| 1548 | return data; | ||
| 1549 | } catch (error) { | 1565 | } catch (error) { |
| 1550 | return []; | 1566 | return []; |
| 1551 | } | 1567 | } |
| @@ -1583,8 +1599,7 @@ async function loadVladSamplers() { | |||
| 1583 | throw new Error('SD.Next returned an error.'); | 1599 | throw new Error('SD.Next returned an error.'); |
| 1584 | } | 1600 | } |
| 1585 | 1601 | ||
| 1586 | const data = await result.json(); | 1602 | return await result.json(); |
| 1587 | return data; | ||
| 1588 | } catch (error) { | 1603 | } catch (error) { |
| 1589 | return []; | 1604 | return []; |
| 1590 | } | 1605 | } |
| @@ -1723,8 +1738,7 @@ async function loadPollinationsModels() { | |||
| 1723 | }); | 1738 | }); |
| 1724 | 1739 | ||
| 1725 | if (result.ok) { | 1740 | if (result.ok) { |
| 1726 | const data = await result.json(); | 1741 | return await result.json(); |
| 1727 | return data; | ||
| 1728 | } | 1742 | } |
| 1729 | 1743 | ||
| 1730 | return []; | 1744 | return []; |
| @@ -1742,8 +1756,7 @@ async function loadTogetherAIModels() { | |||
| 1742 | }); | 1756 | }); |
| 1743 | 1757 | ||
| 1744 | if (result.ok) { | 1758 | if (result.ok) { |
| 1745 | const data = await result.json(); | 1759 | return await result.json(); |
| 1746 | return data; | ||
| 1747 | } | 1760 | } |
| 1748 | 1761 | ||
| 1749 | return []; | 1762 | return []; |
| @@ -1781,8 +1794,7 @@ async function loadNanoGPTModels() { | |||
| 1781 | }); | 1794 | }); |
| 1782 | 1795 | ||
| 1783 | if (result.ok) { | 1796 | if (result.ok) { |
| 1784 | const data = await result.json(); | 1797 | return await result.json(); |
| 1785 | return data; | ||
| 1786 | } | 1798 | } |
| 1787 | 1799 | ||
| 1788 | return []; | 1800 | return []; |
| @@ -1798,8 +1810,10 @@ async function loadHordeModels() { | |||
| 1798 | if (result.ok) { | 1810 | if (result.ok) { |
| 1799 | const data = await result.json(); | 1811 | const data = await result.json(); |
| 1800 | data.sort((a, b) => b.count - a.count); | 1812 | data.sort((a, b) => b.count - a.count); |
| 1801 | const models = data.map(x => ({ value: x.name, text: `${x.name} (ETA: ${x.eta}s, Queue: ${x.queued}, Workers: ${x.count})` })); | 1813 | return data.map(x => ({ |
| 1802 | return models; | 1814 | value: x.name, |
| 1815 | text: `${x.name} (ETA: ${x.eta}s, Queue: ${x.queued}, Workers: ${x.count})`, | ||
| 1816 | })); | ||
| 1803 | } | 1817 | } |
| 1804 | 1818 | ||
| 1805 | return []; | 1819 | return []; |
| @@ -1824,8 +1838,7 @@ async function loadExtrasModels() { | |||
| 1824 | 1838 | ||
| 1825 | if (getModelsResult.ok) { | 1839 | if (getModelsResult.ok) { |
| 1826 | const data = await getModelsResult.json(); | 1840 | const data = await getModelsResult.json(); |
| 1827 | const view_models = data.models.map(x => ({ value: x, text: x })); | 1841 | return data.models.map(x => ({ value: x, text: x })); |
| 1828 | return view_models; | ||
| 1829 | } | 1842 | } |
| 1830 | 1843 | ||
| 1831 | return []; | 1844 | return []; |
| @@ -1867,8 +1880,7 @@ async function loadAutoModels() { | |||
| 1867 | } | 1880 | } |
| 1868 | } | 1881 | } |
| 1869 | 1882 | ||
| 1870 | const data = await result.json(); | 1883 | return await result.json(); |
| 1871 | return data; | ||
| 1872 | } catch (error) { | 1884 | } catch (error) { |
| 1873 | return []; | 1885 | return []; |
| 1874 | } | 1886 | } |
| @@ -1953,8 +1965,7 @@ async function loadVladModels() { | |||
| 1953 | } | 1965 | } |
| 1954 | } | 1966 | } |
| 1955 | 1967 | ||
| 1956 | const data = await result.json(); | 1968 | return await result.json(); |
| 1957 | return data; | ||
| 1958 | } catch (error) { | 1969 | } catch (error) { |
| 1959 | return []; | 1970 | return []; |
| 1960 | } | 1971 | } |
| @@ -2242,7 +2253,7 @@ async function loadComfyWorkflows() { | |||
| 2242 | $('#sd_comfy_workflow').append(option); | 2253 | $('#sd_comfy_workflow').append(option); |
| 2243 | } | 2254 | } |
| 2244 | } catch (error) { | 2255 | } catch (error) { |
| 2245 | return; | 2256 | console.error(`Could not load ComfyUI workflows: ${error.message}`); |
| 2246 | } | 2257 | } |
| 2247 | } | 2258 | } |
| 2248 | 2259 | ||
| @@ -2361,7 +2372,7 @@ function ensureSelectionExists(setting, selector) { | |||
| 2361 | * @param {string} trigger Subject trigger word | 2372 | * @param {string} trigger Subject trigger word |
| 2362 | * @param {string} [message] Chat message | 2373 | * @param {string} [message] Chat message |
| 2363 | * @param {function} [callback] Callback function | 2374 | * @param {function} [callback] Callback function |
| 2364 | * @returns {Promise<string>} Image path | 2375 | * @returns {Promise<string|undefined>} Image path |
| 2365 | */ | 2376 | */ |
| 2366 | async function generatePicture(initiator, args, trigger, message, callback) { | 2377 | async function generatePicture(initiator, args, trigger, message, callback) { |
| 2367 | if (!trigger || trigger.trim().length === 0) { | 2378 | if (!trigger || trigger.trim().length === 0) { |
| @@ -2379,7 +2390,9 @@ async function generatePicture(initiator, args, trigger, message, callback) { | |||
| 2379 | 2390 | ||
| 2380 | trigger = trigger.trim(); | 2391 | trigger = trigger.trim(); |
| 2381 | const generationType = getGenerationType(trigger); | 2392 | const generationType = getGenerationType(trigger); |
| 2382 | console.log('Generation mode', generationType, 'triggered with', trigger); | 2393 | const generationTypeKey = Object.keys(generationMode).find(key => generationMode[key] === generationType); |
| 2394 | console.log(`Generation mode ${generationTypeKey} triggered with "${trigger}"`); | ||
| 2395 | |||
| 2383 | const quietPrompt = getQuietPrompt(generationType, trigger); | 2396 | const quietPrompt = getQuietPrompt(generationType, trigger); |
| 2384 | const context = getContext(); | 2397 | const context = getContext(); |
| 2385 | 2398 | ||
| @@ -2387,11 +2400,11 @@ async function generatePicture(initiator, args, trigger, message, callback) { | |||
| 2387 | ? context.groups[Object.keys(context.groups).filter(x => context.groups[x].id === context.groupId)[0]]?.id?.toString() | 2400 | ? context.groups[Object.keys(context.groups).filter(x => context.groups[x].id === context.groupId)[0]]?.id?.toString() |
| 2388 | : context.characters[context.characterId]?.name; | 2401 | : context.characters[context.characterId]?.name; |
| 2389 | 2402 | ||
| 2390 | if (generationType == generationMode.BACKGROUND) { | 2403 | if (generationType === generationMode.BACKGROUND) { |
| 2391 | const callbackOriginal = callback; | 2404 | const callbackOriginal = callback; |
| 2392 | callback = async function (prompt, imagePath, generationType, _negativePromptPrefix, _initiator, prefixedPrompt) { | 2405 | callback = async function (prompt, imagePath, generationType, _negativePromptPrefix, _initiator, prefixedPrompt) { |
| 2393 | const imgUrl = `url("${encodeURI(imagePath)}")`; | 2406 | const imgUrl = `url("${encodeURI(imagePath)}")`; |
| 2394 | eventSource.emit(event_types.FORCE_SET_BACKGROUND, { url: imgUrl, path: imagePath }); | 2407 | await eventSource.emit(event_types.FORCE_SET_BACKGROUND, { url: imgUrl, path: imagePath }); |
| 2395 | 2408 | ||
| 2396 | if (typeof callbackOriginal === 'function') { | 2409 | if (typeof callbackOriginal === 'function') { |
| 2397 | await callbackOriginal(prompt, imagePath, generationType, negativePromptPrefix, initiator, prefixedPrompt); | 2410 | await callbackOriginal(prompt, imagePath, generationType, negativePromptPrefix, initiator, prefixedPrompt); |
| @@ -2446,12 +2459,12 @@ function setTypeSpecificDimensions(generationType) { | |||
| 2446 | const aspectRatio = extension_settings.sd.width / extension_settings.sd.height; | 2459 | const aspectRatio = extension_settings.sd.width / extension_settings.sd.height; |
| 2447 | 2460 | ||
| 2448 | // Face images are always portrait (pun intended) | 2461 | // Face images are always portrait (pun intended) |
| 2449 | if ((generationType == generationMode.FACE || generationType == generationMode.FACE_MULTIMODAL) && aspectRatio >= 1) { | 2462 | if ((generationType === generationMode.FACE || generationType === generationMode.FACE_MULTIMODAL) && aspectRatio >= 1) { |
| 2450 | // Round to nearest multiple of 64 | 2463 | // Round to nearest multiple of 64 |
| 2451 | extension_settings.sd.height = Math.round(extension_settings.sd.width * 1.5 / 64) * 64; | 2464 | extension_settings.sd.height = Math.round(extension_settings.sd.width * 1.5 / 64) * 64; |
| 2452 | } | 2465 | } |
| 2453 | 2466 | ||
| 2454 | if (generationType == generationMode.BACKGROUND) { | 2467 | if (generationType === generationMode.BACKGROUND) { |
| 2455 | // Background images are always landscape | 2468 | // Background images are always landscape |
| 2456 | if (aspectRatio <= 1) { | 2469 | if (aspectRatio <= 1) { |
| 2457 | // Round to nearest multiple of 64 | 2470 | // Round to nearest multiple of 64 |
| @@ -2537,7 +2550,7 @@ async function getPrompt(generationType, message, trigger, quietPrompt, combineN | |||
| 2537 | */ | 2550 | */ |
| 2538 | function generateFreeModePrompt(trigger, combineNegatives) { | 2551 | function generateFreeModePrompt(trigger, combineNegatives) { |
| 2539 | return trigger | 2552 | return trigger |
| 2540 | .replace(/(?:^char(\s|,)|\{\{charPrefix\}\})/gi, (_, suffix) => { | 2553 | .replace(/^char(\s|,)|{{charPrefix}}/gi, (_, suffix) => { |
| 2541 | const getLastCharacterKey = () => { | 2554 | const getLastCharacterKey = () => { |
| 2542 | if (typeof this_chid !== 'undefined') { | 2555 | if (typeof this_chid !== 'undefined') { |
| 2543 | return getCharaFilename(this_chid); | 2556 | return getCharaFilename(this_chid); |
| @@ -2545,9 +2558,7 @@ function generateFreeModePrompt(trigger, combineNegatives) { | |||
| 2545 | const context = getContext(); | 2558 | const context = getContext(); |
| 2546 | for (let i = context.chat.length - 1; i >= 0; i--) { | 2559 | for (let i = context.chat.length - 1; i >= 0; i--) { |
| 2547 | const message = context.chat[i]; | 2560 | const message = context.chat[i]; |
| 2548 | if (message.is_user || message.is_system) { | 2561 | if (!message.is_user && !message.is_system && typeof message.original_avatar === 'string') { |
| 2549 | continue; | ||
| 2550 | } else if (typeof message.original_avatar === 'string') { | ||
| 2551 | return message.original_avatar.replace(/\.[^/.]+$/, ''); | 2562 | return message.original_avatar.replace(/\.[^/.]+$/, ''); |
| 2552 | } | 2563 | } |
| 2553 | } | 2564 | } |
| @@ -2570,11 +2581,11 @@ function generateFreeModePrompt(trigger, combineNegatives) { | |||
| 2570 | async function generateMultimodalPrompt(generationType, quietPrompt) { | 2581 | async function generateMultimodalPrompt(generationType, quietPrompt) { |
| 2571 | let avatarUrl; | 2582 | let avatarUrl; |
| 2572 | 2583 | ||
| 2573 | if (generationType == generationMode.USER_MULTIMODAL) { | 2584 | if (generationType === generationMode.USER_MULTIMODAL) { |
| 2574 | avatarUrl = getUserAvatarUrl(); | 2585 | avatarUrl = getUserAvatarUrl(); |
| 2575 | } | 2586 | } |
| 2576 | 2587 | ||
| 2577 | if (generationType == generationMode.CHARACTER_MULTIMODAL || generationType === generationMode.FACE_MULTIMODAL) { | 2588 | if (generationType === generationMode.CHARACTER_MULTIMODAL || generationType === generationMode.FACE_MULTIMODAL) { |
| 2578 | avatarUrl = getCharacterAvatarUrl(); | 2589 | avatarUrl = getCharacterAvatarUrl(); |
| 2579 | } | 2590 | } |
| 2580 | 2591 | ||
| @@ -3182,8 +3193,8 @@ function getNovelParams() { | |||
| 3182 | const ratio = Math.sqrt(MAX_PIXELS / (width * height)); | 3193 | const ratio = Math.sqrt(MAX_PIXELS / (width * height)); |
| 3183 | 3194 | ||
| 3184 | // Calculate new width and height while maintaining aspect ratio. | 3195 | // Calculate new width and height while maintaining aspect ratio. |
| 3185 | var newWidth = Math.round(width * ratio); | 3196 | let newWidth = Math.round(width * ratio); |
| 3186 | var newHeight = Math.round(height * ratio); | 3197 | let newHeight = Math.round(height * ratio); |
| 3187 | 3198 | ||
| 3188 | // Ensure new dimensions are multiples of 64. If not, reduce accordingly. | 3199 | // Ensure new dimensions are multiples of 64. If not, reduce accordingly. |
| 3189 | if (newWidth % 64 !== 0) { | 3200 | if (newWidth % 64 !== 0) { |
| @@ -3479,9 +3490,9 @@ async function onComfyOpenWorkflowEditorClick() { | |||
| 3479 | const popupResult = popup.show(); | 3490 | const popupResult = popup.show(); |
| 3480 | const checkPlaceholders = () => { | 3491 | const checkPlaceholders = () => { |
| 3481 | workflow = $('#sd_comfy_workflow_editor_workflow').val().toString(); | 3492 | workflow = $('#sd_comfy_workflow_editor_workflow').val().toString(); |
| 3482 | $('.sd_comfy_workflow_editor_placeholder_list > li[data-placeholder]').each(function (idx) { | 3493 | $('.sd_comfy_workflow_editor_placeholder_list > li[data-placeholder]').each(function () { |
| 3483 | const key = this.getAttribute('data-placeholder'); | 3494 | const key = this.getAttribute('data-placeholder'); |
| 3484 | const found = workflow.search(`"%${key}%"`) != -1; | 3495 | const found = workflow.search(`"%${key}%"`) !== -1; |
| 3485 | this.classList[found ? 'remove' : 'add']('sd_comfy_workflow_editor_not_found'); | 3496 | this.classList[found ? 'remove' : 'add']('sd_comfy_workflow_editor_not_found'); |
| 3486 | }); | 3497 | }); |
| 3487 | }; | 3498 | }; |
| @@ -3841,7 +3852,7 @@ async function sdMessageButton(e) { | |||
| 3841 | swipes.push(image); | 3852 | swipes.push(image); |
| 3842 | 3853 | ||
| 3843 | // If already contains an image and it's not inline - leave it as is | 3854 | // If already contains an image and it's not inline - leave it as is |
| 3844 | message.extra.inline_image = message.extra.image && !message.extra.inline_image ? false : true; | 3855 | message.extra.inline_image = !(message.extra.image && !message.extra.inline_image); |
| 3845 | message.extra.image = image; | 3856 | message.extra.image = image; |
| 3846 | message.extra.title = prompt; | 3857 | message.extra.title = prompt; |
| 3847 | message.extra.generationType = generationType; | 3858 | message.extra.generationType = generationType; |