diff --git a/public/scripts/extensions/stable-diffusion/index.js b/public/scripts/extensions/stable-diffusion/index.js index 6ea16df8c..c9e2fc29e 100644 --- a/public/scripts/extensions/stable-diffusion/index.js +++ b/public/scripts/extensions/stable-diffusion/index.js @@ -906,7 +906,6 @@ async function validateComfyUrl() { throw new Error('URL is not set.'); } - const result = await fetch(`/api/sd/comfy/ping`, { method: 'POST', headers: getRequestHeaders(), @@ -1180,7 +1179,6 @@ async function loadComfySamplers() { } try { - const result = await fetch(`/api/sd/comfy/samplers`, { method: 'POST', headers: getRequestHeaders(), @@ -2037,7 +2035,7 @@ async function generateOpenAiImage(prompt) { /** * Generates an image in ComfyUI using the provided prompt and configuration settings. - * + * * @param {string} prompt - The main instruction used to guide the image generation. * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. */ @@ -2054,8 +2052,8 @@ async function generateComfyImage(prompt) { ]; let workflow = extension_settings.sd.comfy_workflow.replace('"%prompt%"', JSON.stringify(prompt)); - workflow = workflow.replace('"%seed%"', JSON.stringify(Math.round(Math.random()*Number.MAX_SAFE_INTEGER))); - placeholders.forEach(ph=>{ + workflow = workflow.replace('"%seed%"', JSON.stringify(Math.round(Math.random() * Number.MAX_SAFE_INTEGER))); + placeholders.forEach(ph => { workflow = workflow.replace(`"%${ph}%"`, JSON.stringify(extension_settings.sd[ph])); }); console.log(`{ @@ -2071,18 +2069,18 @@ async function generateComfyImage(prompt) { }`, }) }); - return {format:'png', data:await promptResult.text()}; + return { format: 'png', data: await promptResult.text() }; } async function onComfyOpenWorkflowEditorClick() { const editorHtml = $(await $.get('scripts/extensions/stable-diffusion/comfyWorkflowEditor.html')); - const popupResult = callPopup(editorHtml, "confirm", undefined, {okButton: "Save", wide:true, large:true, rows:1 }); - const checkPlaceholders = ()=>{ + const popupResult = callPopup(editorHtml, "confirm", undefined, { okButton: "Save", wide: true, large: true, rows: 1 }); + const checkPlaceholders = () => { const workflow = $('#sd_comfy_workflow_editor_workflow').val().toString(); - $('.sd_comfy_workflow_editor_placeholder_list > li[data-placeholder]').each(function(idx) { + $('.sd_comfy_workflow_editor_placeholder_list > li[data-placeholder]').each(function (idx) { const key = this.getAttribute('data-placeholder'); const found = workflow.search(`"%${key}%"`) != -1; - this.classList[found?'remove':'add']('sd_comfy_workflow_editor_not_found'); + this.classList[found ? 'remove' : 'add']('sd_comfy_workflow_editor_not_found'); }); }; $('#sd_comfy_workflow_editor_workflow').val(extension_settings.sd.comfy_workflow); diff --git a/public/scripts/extensions/stable-diffusion/style.css b/public/scripts/extensions/stable-diffusion/style.css index 374546312..7b9fdd551 100644 --- a/public/scripts/extensions/stable-diffusion/style.css +++ b/public/scripts/extensions/stable-diffusion/style.css @@ -34,28 +34,35 @@ gap: 10px; width: fit-content; } + #sd_comfy_workflow_editor_template { height: 100%; } + .sd_comfy_workflow_editor { display: flex; flex-direction: column; height: 100%; } + .sd_comfy_workflow_editor_content { display: flex; flex: 1 1 auto; flex-direction: row; } + .sd_comfy_workflow_editor_workflow_container { flex: 1 1 auto; } + #sd_comfy_workflow_editor_workflow { font-family: monospace; } + .sd_comfy_workflow_editor_placeholder_container { flex: 0 0 auto; } + .sd_comfy_workflow_editor_placeholder_list { font-size: x-small; list-style: none; @@ -63,12 +70,15 @@ padding: 3px 5px; text-align: left; } -.sd_comfy_workflow_editor_placeholder_list > li[data-placeholder]:before { + +.sd_comfy_workflow_editor_placeholder_list>li[data-placeholder]:before { content: "✅ "; } -.sd_comfy_workflow_editor_placeholder_list > li.sd_comfy_workflow_editor_not_found:before { + +.sd_comfy_workflow_editor_placeholder_list>li.sd_comfy_workflow_editor_not_found:before { content: "❌ "; } -.sd_comfy_workflow_editor_placeholder_list > li > .notes-link { + +.sd_comfy_workflow_editor_placeholder_list>li>.notes-link { cursor: help; -} \ No newline at end of file +} diff --git a/src/stable-diffusion.js b/src/stable-diffusion.js index 303bbaf7e..cfec97e98 100644 --- a/src/stable-diffusion.js +++ b/src/stable-diffusion.js @@ -348,91 +348,90 @@ function registerEndpoints(app, jsonParser) { } }); + app.post('/api/sd/comfy/ping', jsonParser, async (request, response) => { + try { + const url = new URL(request.body.url); + url.pathname = '/system_stats' - app.post('/api/sd/comfy/ping', jsonParser, async(request, response)=>{ - try { - const url = new URL(request.body.url); - url.pathname = '/system_stats' + const result = await fetch(url); + if (!result.ok) { + throw new Error('ComfyUI returned an error.'); + } - const result = await fetch(url); - if (!result.ok) { - throw new Error('ComfyUI returned an error.'); - } - - return response.sendStatus(200); - } catch (error) { - console.log(error); - return response.sendStatus(500); - } - }); + return response.sendStatus(200); + } catch (error) { + console.log(error); + return response.sendStatus(500); + } + }); - app.post('/api/sd/comfy/samplers', jsonParser, async(request, response)=>{ - try { - const url = new URL(request.body.url); - url.pathname = '/object_info' + app.post('/api/sd/comfy/samplers', jsonParser, async (request, response) => { + try { + const url = new URL(request.body.url); + url.pathname = '/object_info' - const result = await fetch(url); - if (!result.ok) { - throw new Error('ComfyUI returned an error.'); - } + const result = await fetch(url); + if (!result.ok) { + throw new Error('ComfyUI returned an error.'); + } - const data = await result.json(); - return response.send(data.KSampler.input.required.sampler_name[0]); - } catch (error) { - console.log(error); - return response.sendStatus(500); - } - }); - - app.post('/api/sd/comfy/models', jsonParser, async(request, response)=>{ - try { - const url = new URL(request.body.url); - url.pathname = '/object_info' - - const result = await fetch(url); - if (!result.ok) { - throw new Error('ComfyUI returned an error.'); - } const data = await result.json(); - return response.send(data.CheckpointLoaderSimple.input.required.ckpt_name[0].map(it=>({value:it,text:it}))); - } catch (error) { - console.log(error); - return response.sendStatus(500); - } - }); + return response.send(data.KSampler.input.required.sampler_name[0]); + } catch (error) { + console.log(error); + return response.sendStatus(500); + } + }); - app.post('/api/sd/comfy/schedulers', jsonParser, async(request, response)=>{ - try { - const url = new URL(request.body.url); - url.pathname = '/object_info' + app.post('/api/sd/comfy/models', jsonParser, async (request, response) => { + try { + const url = new URL(request.body.url); + url.pathname = '/object_info' - const result = await fetch(url); - if (!result.ok) { - throw new Error('ComfyUI returned an error.'); - } + const result = await fetch(url); + if (!result.ok) { + throw new Error('ComfyUI returned an error.'); + } + const data = await result.json(); + return response.send(data.CheckpointLoaderSimple.input.required.ckpt_name[0].map(it => ({ value: it, text: it }))); + } catch (error) { + console.log(error); + return response.sendStatus(500); + } + }); - const data = await result.json(); - return response.send(data.KSampler.input.required.scheduler[0]); - } catch (error) { - console.log(error); - return response.sendStatus(500); - } - }); + app.post('/api/sd/comfy/schedulers', jsonParser, async (request, response) => { + try { + const url = new URL(request.body.url); + url.pathname = '/object_info' - app.post('/api/sd/comfy/generate', jsonParser, async(request, response)=>{ - try { - const url = new URL(request.body.url); - url.pathname = '/prompt' + const result = await fetch(url); + if (!result.ok) { + throw new Error('ComfyUI returned an error.'); + } - const promptResult = await fetch(url, { + const data = await result.json(); + return response.send(data.KSampler.input.required.scheduler[0]); + } catch (error) { + console.log(error); + return response.sendStatus(500); + } + }); + + app.post('/api/sd/comfy/generate', jsonParser, async (request, response) => { + try { + const url = new URL(request.body.url); + url.pathname = '/prompt' + + const promptResult = await fetch(url, { method: 'POST', body: request.body.prompt, }); - if (!promptResult.ok) { - throw new Error('ComfyUI returned an error.'); - } + if (!promptResult.ok) { + throw new Error('ComfyUI returned an error.'); + } - const data = await promptResult.json(); + const data = await promptResult.json(); const id = data.prompt_id; let item; const historyUrl = new URL(request.body.url); @@ -449,7 +448,7 @@ function registerEndpoints(app, jsonParser) { } await delay(100); } - const imgInfo = Object.keys(item.outputs).map(it=>item.outputs[it].images).flat()[0]; + const imgInfo = Object.keys(item.outputs).map(it => item.outputs[it].images).flat()[0]; const imgUrl = new URL(request.body.url); imgUrl.pathname = '/view'; imgUrl.search = `?filename=${imgInfo.filename}&subfolder=${imgInfo.subfolder}&type=${imgInfo.type}`; @@ -459,10 +458,10 @@ function registerEndpoints(app, jsonParser) { } const imgBuffer = await imgResponse.buffer(); return response.send(imgBuffer.toString('base64')); - } catch (error) { - return response.sendStatus(500); - } - }); + } catch (error) { + return response.sendStatus(500); + } + }); } module.exports = {