Fixed SD RPG
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
const $ = (id) => document.getElementById(id);
|
||||
|
||||
function fmt(obj) {
|
||||
return typeof obj === 'string' ? obj : JSON.stringify(obj, null, 2);
|
||||
}
|
||||
|
||||
async function api(path, opts = {}) {
|
||||
const res = await fetch(path, {
|
||||
headers: { 'Content-Type': 'application/json', ...(opts.headers || {}) },
|
||||
...opts,
|
||||
});
|
||||
const text = await res.text();
|
||||
let data;
|
||||
try {
|
||||
data = JSON.parse(text);
|
||||
} catch {
|
||||
data = text;
|
||||
}
|
||||
if (!res.ok) {
|
||||
const detail = data?.detail || text || res.statusText;
|
||||
throw new Error(`${res.status}: ${detail}`);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function initTabs() {
|
||||
const tabs = document.querySelectorAll('#debugTabs button');
|
||||
tabs.forEach((btn) => {
|
||||
btn.addEventListener('click', () => {
|
||||
tabs.forEach((t) => t.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
document.querySelectorAll('.debug-panel').forEach((p) => p.classList.remove('active'));
|
||||
$(`panel-${btn.dataset.tab}`).classList.add('active');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function loadConfig() {
|
||||
const c = await api('/debug/config');
|
||||
$('configOut').textContent = fmt(c);
|
||||
$('llmModel').placeholder = c.sd_prompt_model || c.system_model;
|
||||
return c;
|
||||
}
|
||||
|
||||
async function loadPersonas() {
|
||||
const list = await api('/debug/personas');
|
||||
const sel = $('sdPersona');
|
||||
sel.innerHTML = '';
|
||||
for (const p of list) {
|
||||
const opt = document.createElement('option');
|
||||
opt.value = p.persona_id;
|
||||
opt.textContent = `${p.name} (${p.persona_id})`;
|
||||
sel.appendChild(opt);
|
||||
}
|
||||
}
|
||||
|
||||
async function runSdPrompt() {
|
||||
$('sdScene').textContent = '…';
|
||||
$('sdPrompts').textContent = '…';
|
||||
const body = {
|
||||
persona_id: $('sdPersona').value,
|
||||
chat_excerpt: $('sdChat').value,
|
||||
outfit_json: $('sdOutfit').value || '[]',
|
||||
use_prose: $('sdUseProse') ? $('sdUseProse').checked : false,
|
||||
};
|
||||
const app = $('sdAppearance').value.trim();
|
||||
if (app) body.appearance_override = app;
|
||||
|
||||
const data = await api('/debug/sd-prompt', { method: 'POST', body: JSON.stringify(body) });
|
||||
$('sdScene').textContent = data.scene ? fmt(data.scene) : (data.error || '—');
|
||||
const prompts = [];
|
||||
if (data.tags_only_full) prompts.push('=== TAGS + POV (no prose) ===\n' + data.tags_only_full);
|
||||
if (data.hybrid_full) prompts.push('\n=== HYBRID (Comfy) ===\n' + data.hybrid_full);
|
||||
if (!data.tags_only_full && data.tag_full) prompts.push('=== PROMPT ===\n' + data.tag_full);
|
||||
$('sdPrompts').textContent = prompts.join('\n') || data.error || '—';
|
||||
$('sdLlmRaw').textContent = [
|
||||
`model: ${data.sd_prompt_model}`,
|
||||
`dual: ${data.anima_dual}`,
|
||||
'',
|
||||
'--- system ---',
|
||||
data.builder_system || '',
|
||||
'',
|
||||
'--- user ---',
|
||||
data.builder_user || '',
|
||||
'',
|
||||
'--- raw ---',
|
||||
data.llm_raw || data.error || '',
|
||||
].join('\n');
|
||||
if (data.tag_full || data.hybrid_full) {
|
||||
const src = data.hybrid_full || data.tag_full;
|
||||
const parts = src.includes('__NEGATIVE_PROMPT__')
|
||||
? src.split('\n\n__NEGATIVE_PROMPT__\n\n')
|
||||
: src.includes('\n\nNegative prompt:')
|
||||
? src.split('\n\nNegative prompt:')
|
||||
: [src, ''];
|
||||
$('genPositive').value = parts[0] || '';
|
||||
$('genNegative').value = parts[1] || '';
|
||||
}
|
||||
}
|
||||
|
||||
async function runLlm() {
|
||||
$('llmOut').textContent = '…';
|
||||
const data = await api('/debug/llm', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
model: $('llmModel').value.trim(),
|
||||
system: $('llmSystem').value,
|
||||
user: $('llmUser').value,
|
||||
}),
|
||||
});
|
||||
$('llmOut').textContent = `model: ${data.model}\n\n${data.response}`;
|
||||
}
|
||||
|
||||
function fillModelSelect(sel, options, configured) {
|
||||
const current = sel.querySelector('option')?.value ?? '';
|
||||
sel.innerHTML = `<option value="">— env: ${configured || '—'} —</option>`;
|
||||
for (const name of options || []) {
|
||||
const opt = document.createElement('option');
|
||||
opt.value = name;
|
||||
opt.textContent = name;
|
||||
if (name === configured) opt.selected = true;
|
||||
sel.appendChild(opt);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadComfyModels() {
|
||||
$('comfyModelLists').textContent = 'Загрузка object_info…';
|
||||
const data = await api('/debug/comfy/models');
|
||||
const { models, configured } = data;
|
||||
fillModelSelect($('genUnet'), models.unets, configured.unet);
|
||||
fillModelSelect($('genClip'), models.clips, configured.clip);
|
||||
fillModelSelect($('genVae'), models.vaes, configured.vae);
|
||||
fillModelSelect($('genCkpt'), models.checkpoints, configured.checkpoint);
|
||||
|
||||
const wrap = $('comfyModelLists');
|
||||
wrap.innerHTML = '';
|
||||
for (const [key, list] of Object.entries(models)) {
|
||||
const block = document.createElement('details');
|
||||
block.className = 'model-list-block';
|
||||
block.open = key === 'unets' || key === 'checkpoints';
|
||||
block.innerHTML = `<summary>${key} (${list.length})</summary>`;
|
||||
const ul = document.createElement('ul');
|
||||
for (const item of list) {
|
||||
const li = document.createElement('li');
|
||||
li.textContent = item;
|
||||
ul.appendChild(li);
|
||||
}
|
||||
block.appendChild(ul);
|
||||
wrap.appendChild(block);
|
||||
}
|
||||
}
|
||||
|
||||
async function comfyPing() {
|
||||
$('comfyPingOut').textContent = '…';
|
||||
const data = await api('/debug/comfy/ping');
|
||||
$('comfyPingOut').textContent = fmt(data);
|
||||
}
|
||||
|
||||
async function comfyGenerate() {
|
||||
$('comfyGenOut').textContent = 'Генерация…';
|
||||
$('comfyImgWrap').classList.add('hidden');
|
||||
const body = {
|
||||
positive: $('genPositive').value,
|
||||
negative: $('genNegative').value,
|
||||
};
|
||||
const u = $('genUnet').value;
|
||||
const c = $('genClip').value;
|
||||
const v = $('genVae').value;
|
||||
const ck = $('genCkpt').value;
|
||||
if (u) body.unet = u;
|
||||
if (c) body.clip = c;
|
||||
if (v) body.vae = v;
|
||||
if (ck) body.checkpoint = ck;
|
||||
|
||||
const data = await api('/debug/comfy/generate', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
$('comfyGenOut').textContent = fmt(data);
|
||||
if (data.image_path) {
|
||||
$('comfyImg').src = data.image_path + '?t=' + Date.now();
|
||||
$('comfyImgWrap').classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
async function comfyRaw() {
|
||||
$('comfyRawOut').textContent = '…';
|
||||
const data = await api('/debug/comfy/raw', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
method: $('rawMethod').value,
|
||||
path: $('rawPath').value,
|
||||
params_json: $('rawParams').value || '{}',
|
||||
body_json: $('rawBody').value || '',
|
||||
}),
|
||||
});
|
||||
$('comfyRawOut').textContent = fmt(data);
|
||||
}
|
||||
|
||||
function bind() {
|
||||
initTabs();
|
||||
$('btnReloadConfig').addEventListener('click', loadConfig);
|
||||
$('btnSdPrompt').addEventListener('click', () => runSdPrompt().catch(showErr));
|
||||
$('btnLlm').addEventListener('click', () => runLlm().catch(showErr));
|
||||
$('btnComfyPing').addEventListener('click', () => comfyPing().catch(showErr));
|
||||
$('btnComfyModels').addEventListener('click', () => loadComfyModels().catch(showErr));
|
||||
$('btnComfyGen').addEventListener('click', () => comfyGenerate().catch(showErr));
|
||||
$('btnComfyRaw').addEventListener('click', () => comfyRaw().catch(showErr));
|
||||
}
|
||||
|
||||
function showErr(e) {
|
||||
alert(e.message || String(e));
|
||||
}
|
||||
|
||||
bind();
|
||||
loadConfig().catch(showErr);
|
||||
loadPersonas().catch(showErr);
|
||||
Reference in New Issue
Block a user