diff --git a/public/scripts/extensions/stable-diffusion/comfyWorkflowEditor.html b/public/scripts/extensions/stable-diffusion/comfyWorkflowEditor.html
index 29ebb9197..f5001dba4 100644
--- a/public/scripts/extensions/stable-diffusion/comfyWorkflowEditor.html
+++ b/public/scripts/extensions/stable-diffusion/comfyWorkflowEditor.html
@@ -25,6 +25,12 @@
?
+
Custom
+
+ +
+
+
diff --git a/public/scripts/extensions/stable-diffusion/index.js b/public/scripts/extensions/stable-diffusion/index.js
index e648809ac..8bb40d059 100644
--- a/public/scripts/extensions/stable-diffusion/index.js
+++ b/public/scripts/extensions/stable-diffusion/index.js
@@ -16,6 +16,7 @@ import {
user_avatar,
getCharacterAvatar,
formatCharacterAvatar,
+ substituteParams,
} from '../../../script.js';
import { getApiUrl, getContext, extension_settings, doExtrasFetch, modules, renderExtensionTemplate } from '../../extensions.js';
import { selected_group } from '../../group-chats.js';
@@ -24,6 +25,7 @@ import { getMessageTimeStamp, humanizedDateTime } from '../../RossAscends-mods.j
import { SECRET_KEYS, secret_state } from '../../secrets.js';
import { getNovelUnlimitedImageGeneration, getNovelAnlas, loadNovelSubscriptionData } from '../../nai-settings.js';
import { getMultimodalCaption } from '../shared.js';
+import { registerSlashCommand } from '../../slash-commands.js';
export { MODULE_NAME };
// Wraps a string into monospace font-face span
@@ -830,6 +832,16 @@ function onComfyWorkflowChange() {
extension_settings.sd.comfy_workflow = $('#sd_comfy_workflow').find(':selected').val();
saveSettingsDebounced();
}
+async function changeComfyWorkflow(_, name) {
+ name = name.replace(/(\.json)?$/i, '.json');
+ if ($(`#sd_comfy_workflow > [value="${name}"]`).length > 0) {
+ extension_settings.sd.comfy_workflow = name;
+ $('#sd_comfy_workflow').val(extension_settings.sd.comfy_workflow);
+ saveSettingsDebounced();
+ } else {
+ toastr.error(`ComfyUI Workflow "${name}" does not exist.`);
+ }
+}
async function validateAutoUrl() {
try {
@@ -2180,6 +2192,9 @@ async function generateComfyImage(prompt) {
placeholders.forEach(ph => {
workflow = workflow.replace(`"%${ph}%"`, JSON.stringify(extension_settings.sd[ph]));
});
+ (extension_settings.sd.comfy_placeholders ?? []).forEach(ph => {
+ workflow = workflow.replace(`"%${ph.find}%"`, JSON.stringify(substituteParams(ph.replace)));
+ });
console.log(`{
"prompt": ${workflow}
}`);
@@ -2216,6 +2231,50 @@ async function onComfyOpenWorkflowEditorClick() {
};
$('#sd_comfy_workflow_editor_name').text(extension_settings.sd.comfy_workflow);
$('#sd_comfy_workflow_editor_workflow').val(workflow);
+ const addPlaceholderDom = (placeholder) => {
+ const el = $(`
+
+ ⊘
+ "%${placeholder.find}%"
+
+
+
+ `);
+ $('#sd_comfy_workflow_editor_placeholder_list_custom').append(el);
+ el.find('.sd_comfy_workflow_editor_custom_find').val(placeholder.find);
+ el.find('.sd_comfy_workflow_editor_custom_find').on('input', function() {
+ placeholder.find = this.value;
+ el.find('.sd_comfy_workflow_editor_custom_final').text(`"%${this.value}%"`);
+ el.attr('data-placeholder', `${this.value}`);
+ checkPlaceholders();
+ saveSettingsDebounced();
+ });
+ el.find('.sd_comfy_workflow_editor_custom_replace').val(placeholder.replace);
+ el.find('.sd_comfy_workflow_editor_custom_replace').on('input', function() {
+ placeholder.replace = this.value;
+ saveSettingsDebounced();
+ });
+ el.find('.sd_comfy_workflow_editor_custom_remove').on('click', () => {
+ el.remove();
+ extension_settings.sd.comfy_placeholders.splice(extension_settings.sd.comfy_placeholders.indexOf(placeholder));
+ saveSettingsDebounced();
+ });
+ };
+ $('#sd_comfy_workflow_editor_placeholder_add').on('click', () => {
+ if (!extension_settings.sd.comfy_placeholders) {
+ extension_settings.sd.comfy_placeholders = [];
+ }
+ const placeholder = {
+ find: '',
+ replace: '',
+ };
+ extension_settings.sd.comfy_placeholders.push(placeholder);
+ addPlaceholderDom(placeholder);
+ saveSettingsDebounced();
+ });
+ (extension_settings.sd.comfy_placeholders ?? []).forEach(placeholder=>{
+ addPlaceholderDom(placeholder);
+ });
checkPlaceholders();
$('#sd_comfy_workflow_editor_workflow').on('input', checkPlaceholders);
if (await popupResult) {
@@ -2481,7 +2540,8 @@ $('#sd_dropdown [id]').on('click', function () {
});
jQuery(async () => {
- getContext().registerSlashCommand('imagine', generatePicture, ['sd', 'img', 'image'], helpString, true, true);
+ registerSlashCommand('imagine', generatePicture, ['sd', 'img', 'image'], helpString, true, true);
+ registerSlashCommand('imagine-comfy-workflow', changeComfyWorkflow, ['icw'], '(workflowName) - change the workflow to be used for image generation with ComfyUI, e.g. /imagine-comfy-workflow MyWorkflow')
$('#extensions_settings').append(renderExtensionTemplate('stable-diffusion', 'settings', defaultSettings));
$('#sd_source').on('change', onSourceChange);
diff --git a/public/scripts/extensions/stable-diffusion/style.css b/public/scripts/extensions/stable-diffusion/style.css
index 7b9fdd551..139cf3f09 100644
--- a/public/scripts/extensions/stable-diffusion/style.css
+++ b/public/scripts/extensions/stable-diffusion/style.css
@@ -82,3 +82,17 @@
.sd_comfy_workflow_editor_placeholder_list>li>.notes-link {
cursor: help;
}
+
+.sd_comfy_workflow_editor_placeholder_list input {
+ font-size: inherit;
+ margin: 0;
+}
+.sd_comfy_workflow_editor_custom_remove, #sd_comfy_workflow_editor_placeholder_add {
+ cursor: pointer;
+ font-weight: bold;
+ width: 1em;
+ opacity: 0.5;
+ &:hover {
+ opacity: 1;
+ }
+}
diff --git a/public/scripts/group-chats.js b/public/scripts/group-chats.js
index 7108a9914..bfd49f7c8 100644
--- a/public/scripts/group-chats.js
+++ b/public/scripts/group-chats.js
@@ -1108,7 +1108,7 @@ function printGroupCandidates() {
showNavigator: true,
showSizeChanger: true,
pageSize: Number(localStorage.getItem(storageKey)) || 5,
- sizeChangerOptions: [5, 10, 25, 50, 100, 200],
+ sizeChangerOptions: [5, 10, 25, 50, 100, 200, 500, 1000],
afterSizeSelectorChange: function (e) {
localStorage.setItem(storageKey, e.target.value);
},
@@ -1135,7 +1135,7 @@ function printGroupMembers() {
showNavigator: true,
showSizeChanger: true,
pageSize: Number(localStorage.getItem(storageKey)) || 5,
- sizeChangerOptions: [5, 10, 25, 50, 100, 200],
+ sizeChangerOptions: [5, 10, 25, 50, 100, 200, 500, 1000],
afterSizeSelectorChange: function (e) {
localStorage.setItem(storageKey, e.target.value);
},
diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js
index 1768762db..23ca73a56 100644
--- a/public/scripts/slash-commands.js
+++ b/public/scripts/slash-commands.js
@@ -842,6 +842,36 @@ async function unhideMessageCallback(_, arg) {
return '';
}
+/**
+ * Copium for running group actions when the member is offscreen.
+ * @param {number} chid - character ID
+ * @param {string} action - one of 'enable', 'disable', 'up', 'down', 'peek', 'remove'
+ * @returns {void}
+ */
+function performGroupMemberAction(chid, action) {
+ const memberSelector = `.group_member[chid="${chid}"]`;
+ // Do not optimize. Paginator gets recreated on every action
+ const paginationSelector = '#rm_group_members_pagination';
+ const pageSizeSelector = '#rm_group_members_pagination select';
+ let wasOffscreen = false;
+ let paginationValue = null;
+ let pageValue = null;
+
+ if ($(memberSelector).length === 0) {
+ wasOffscreen = true;
+ paginationValue = Number($(pageSizeSelector).val());
+ pageValue = $(paginationSelector).pagination('getCurrentPageNum');
+ $(pageSizeSelector).val($(pageSizeSelector).find('option').last().val()).trigger('change');
+ }
+
+ $(memberSelector).find(`[data-action="${action}"]`).trigger('click');
+
+ if (wasOffscreen) {
+ $(pageSizeSelector).val(paginationValue).trigger('change');
+ $(paginationSelector).pagination('go', pageValue);
+ }
+}
+
async function disableGroupMemberCallback(_, arg) {
if (!selected_group) {
toastr.warning('Cannot run /disable command outside of a group chat.');
@@ -855,7 +885,7 @@ async function disableGroupMemberCallback(_, arg) {
return '';
}
- $(`.group_member[chid="${chid}"] [data-action="disable"]`).trigger('click');
+ performGroupMemberAction(chid, 'disable');
return '';
}
@@ -872,7 +902,7 @@ async function enableGroupMemberCallback(_, arg) {
return '';
}
- $(`.group_member[chid="${chid}"] [data-action="enable"]`).trigger('click');
+ performGroupMemberAction(chid, 'enable');
return '';
}
@@ -889,7 +919,7 @@ async function moveGroupMemberUpCallback(_, arg) {
return '';
}
- $(`.group_member[chid="${chid}"] [data-action="up"]`).trigger('click');
+ performGroupMemberAction(chid, 'up');
return '';
}
@@ -906,7 +936,7 @@ async function moveGroupMemberDownCallback(_, arg) {
return '';
}
- $(`.group_member[chid="${chid}"] [data-action="down"]`).trigger('click');
+ performGroupMemberAction(chid, 'down');
return '';
}
@@ -928,7 +958,7 @@ async function peekCallback(_, arg) {
return '';
}
- $(`.group_member[chid="${chid}"] [data-action="view"]`).trigger('click');
+ performGroupMemberAction(chid, 'peek');
return '';
}
@@ -950,7 +980,7 @@ async function removeGroupMemberCallback(_, arg) {
return '';
}
- $(`.group_member[chid="${chid}"] [data-action="remove"]`).trigger('click');
+ performGroupMemberAction(chid, 'remove');
return '';
}