mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-01-20 13:38:49 +01:00
move requests to comfy into ST server
This commit is contained in:
parent
fdccab3069
commit
9dd1e59421
@ -879,7 +879,14 @@ async function validateComfyUrl() {
|
||||
throw new Error('URL is not set.');
|
||||
}
|
||||
|
||||
const result = await fetch(`${extension_settings.sd.comfy_url}/system_stats`);
|
||||
|
||||
const result = await fetch(`/api/sd/comfy/ping`, {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify({
|
||||
url: extension_settings.sd.comfy_url,
|
||||
})
|
||||
});
|
||||
if (!result.ok) {
|
||||
throw new Error('ComfyUI returned an error.');
|
||||
}
|
||||
@ -1146,12 +1153,18 @@ async function loadComfySamplers() {
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await fetch(`${extension_settings.sd.comfy_url}/object_info`);
|
||||
|
||||
const result = await fetch(`/api/sd/comfy/samplers`, {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify({
|
||||
url: extension_settings.sd.comfy_url,
|
||||
})
|
||||
});
|
||||
if (!result.ok) {
|
||||
throw new Error('ComfyUI returned an error.');
|
||||
}
|
||||
const data = await result.json();
|
||||
return data.KSampler.input.required.sampler_name[0];
|
||||
return await result.json();
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
@ -1366,12 +1379,17 @@ async function loadComfyModels() {
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await fetch(`${extension_settings.sd.comfy_url}/object_info`);
|
||||
const result = await fetch(`/api/sd/comfy/models`, {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify({
|
||||
url: extension_settings.sd.comfy_url,
|
||||
})
|
||||
});
|
||||
if (!result.ok) {
|
||||
throw new Error('ComfyUI returned an error.');
|
||||
}
|
||||
const data = await result.json();
|
||||
return data.CheckpointLoaderSimple.input.required.ckpt_name[0].map(it=>({value:it,text:it}));
|
||||
return await result.json();
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
@ -1420,12 +1438,17 @@ async function loadComfySchedulers() {
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await fetch(`${extension_settings.sd.comfy_url}/object_info`);
|
||||
const result = await fetch(`/api/sd/comfy/schedulers`, {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify({
|
||||
url: extension_settings.sd.comfy_url,
|
||||
})
|
||||
});
|
||||
if (!result.ok) {
|
||||
throw new Error('ComfyUI returned an error.');
|
||||
}
|
||||
const data = await result.json();
|
||||
return data.KSampler.input.required.scheduler[0];
|
||||
return await result.json();
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
@ -1950,54 +1973,17 @@ async function generateComfyImage(prompt) {
|
||||
console.log(`{
|
||||
"prompt": ${workflow}
|
||||
}`);
|
||||
const promptResult = await fetch(`${extension_settings.sd.comfy_url}/prompt`, {
|
||||
const promptResult = await fetch(`/api/sd/comfy/generate`, {
|
||||
method: 'POST',
|
||||
body: `{
|
||||
"prompt": ${workflow}
|
||||
}`
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify({
|
||||
url: extension_settings.sd.comfy_url,
|
||||
prompt: `{
|
||||
"prompt": ${workflow}
|
||||
}`,
|
||||
})
|
||||
});
|
||||
if (promptResult.ok) {
|
||||
const id = (await promptResult.json()).prompt_id;
|
||||
let item;
|
||||
while (true) {
|
||||
const result = await fetch(`${extension_settings.sd.comfy_url}/history`);
|
||||
if (result.ok) {
|
||||
const history = await result.json();
|
||||
item = history[id];
|
||||
if (item) {
|
||||
break;
|
||||
}
|
||||
await new Promise(resolve=>window.setTimeout(resolve, 100));
|
||||
} else {
|
||||
const text = await result.text();
|
||||
throw new Error(text);
|
||||
}
|
||||
}
|
||||
const imgInfo = Object.keys(item.outputs).map(it=>item.outputs[it].images).flat()[0];
|
||||
let img;
|
||||
await new Promise(resolve=>{
|
||||
img = new Image();
|
||||
img.crossOrigin = 'anonymous';
|
||||
img.addEventListener('load', resolve);
|
||||
img.addEventListener('error', (...v)=>{
|
||||
throw new Error('failed to load image');
|
||||
});
|
||||
img.src = `${extension_settings.sd.comfy_url}/view?filename=${imgInfo.filename}&subfolder=${imgInfo.subfolder}&type=${imgInfo.type}`;
|
||||
});
|
||||
const canvas = new OffscreenCanvas(extension_settings.sd.width, extension_settings.sd.height);
|
||||
const con = canvas.getContext('2d');
|
||||
con.drawImage(img, 0,0);
|
||||
const imgBlob = await canvas.convertToBlob();
|
||||
const dataUrl = await new Promise(resolve=>{
|
||||
const reader = new FileReader();
|
||||
reader.addEventListener('load', ()=>resolve(reader.result));
|
||||
reader.readAsDataURL(imgBlob);
|
||||
});
|
||||
return {format:'png', data:dataUrl.split(',').pop()};
|
||||
} else {
|
||||
const text = await promptResult.text();
|
||||
throw new Error(text);
|
||||
}
|
||||
return {format:'png', data:await promptResult.text()};
|
||||
}
|
||||
|
||||
async function onComfyOpenWorkflowEditorClick() {
|
||||
|
@ -128,7 +128,7 @@
|
||||
<i class="fa-solid fa-pen-to-square"></i>
|
||||
<span>Open Workflow Editor</span>
|
||||
</div>
|
||||
<p><i><b>Important:</b> run ComfyUI with the <code>--enable-cors-header http://127.0.0.1:8000</code> argument (adjust URL according to your SillyTavern setup)! The server must be accessible from the SillyTavern host machine.</i></p>
|
||||
<p><i><b>Important:</b> The server must be accessible from the SillyTavern host machine.</i></p>
|
||||
</div>
|
||||
<label for="sd_scale">CFG Scale (<span id="sd_scale_value"></span>)</label>
|
||||
<input id="sd_scale" type="range" min="{{scale_min}}" max="{{scale_max}}" step="{{scale_step}}" value="{{scale}}" />
|
||||
|
@ -347,6 +347,122 @@ function registerEndpoints(app, jsonParser) {
|
||||
return response.send({ prompt: originalPrompt });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
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.');
|
||||
}
|
||||
|
||||
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'
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/api/sd/comfy/schedulers', 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.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.');
|
||||
}
|
||||
|
||||
const data = await promptResult.json();
|
||||
const id = data.prompt_id;
|
||||
let item;
|
||||
const historyUrl = new URL(request.body.url);
|
||||
historyUrl.pathname = '/history';
|
||||
while (true) {
|
||||
const result = await fetch(historyUrl);
|
||||
if (!result.ok) {
|
||||
throw new Error('ComfyUI returned an error.');
|
||||
}
|
||||
const history = await result.json();
|
||||
item = history[id];
|
||||
if (item) {
|
||||
break;
|
||||
}
|
||||
await delay(100);
|
||||
}
|
||||
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}`;
|
||||
const imgResponse = await fetch(imgUrl);
|
||||
if (!imgResponse.ok) {
|
||||
throw new Error('ComfyUI returned an error.');
|
||||
}
|
||||
const imgBuffer = await imgResponse.buffer();
|
||||
return response.send(imgBuffer.toString('base64'));
|
||||
} catch (error) {
|
||||
return response.sendStatus(500);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
Loading…
Reference in New Issue
Block a user