Add /debug slash command for a short Assistent state dump.

Shows live params, Exact/session defaults, last patch, and a brief why-priority note without calling the LLM.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leonid Pershin
2026-08-21 23:33:17 +03:00
co-authored by Cursor
parent ae1fb29687
commit 6d487726ef
3 changed files with 100 additions and 1 deletions
+97
View File
@@ -66,6 +66,7 @@
let HELP_TEXT = `Slash-команды (без LLM):
/help — этот список
/debug — сводка: промпт, params, Exact/session, почему так
/gen — Generate сейчас
/look generate|refN — прикрепить окно к vision
/init /mask /clear — Init / Mask / Clear Init
@@ -81,6 +82,7 @@
let SLASH_COMMANDS = [
{ cmd: '/help', hint: 'список команд' },
{ cmd: '/debug', hint: 'сводка настроек' },
{ cmd: '/gen', hint: 'Generate сейчас' },
{ cmd: '/look ', hint: 'generate|refN' },
{ cmd: '/init', hint: 'как Init' },
@@ -4349,6 +4351,96 @@
box.scrollTop = box.scrollHeight;
}
function clipDebug(s, max) {
const t = String(s || '').replace(/\s+/g, ' ').trim();
if (!t) {
return '—';
}
return t.length > max ? `${t.slice(0, max)}` : t;
}
function formatDebugLoras(list) {
if (!Array.isArray(list) || !list.length) {
return 'нет';
}
return list.slice(0, 8).map((l) => {
const name = l?.name || l;
const w = l?.weight != null ? `@${l.weight}` : '';
return `${name}${w}`;
}).join(', ');
}
function buildDebugSummary() {
const persona = $('sa_persona')?.value || 'neutral';
const pack = $('sa_pack')?.value || 'write_prompt';
const chatModel = $('sa_model')?.value || '—';
const embed = $('sa_embed_model')?.value || state.preferredEmbed || '—';
const profile = detectKreaProfileName();
const defaults = mergedGenerationDefaults(profile);
const session = state.sessionExact || {};
const exactGen = state.exact?.generation || state.config?.exact?.generation || {};
const ctx = (() => {
try {
return collectLiveContext();
} catch (e) {
return {};
}
})();
const aspect = guessAspectFromSize(ctx.width, ctx.height) || defaults.aspect || '—';
const why = [];
if (Object.keys(session).length) {
why.push(`session_exact перекрывает Exact: ${Object.keys(session).join(', ')}`);
} else {
why.push('session_exact пуст — params из Exact + профиль чекпоинта');
}
why.push(`профиль чекпоинта: ${profile} (имя/title → turbo|raw)`);
if (persona === 'cinema' || state.exact?.generation?.aspect) {
why.push(`persona/exact aspect: ${state.exact?.generation?.aspect || exactGen.aspect || '—'}`);
}
if (state.lastPatch) {
const keys = Object.keys(state.lastPatch).filter((k) => state.lastPatch[k] != null && k !== 'notes');
why.push(`последний патч задал: ${keys.slice(0, 12).join(', ')}`);
} else {
why.push('последнего патча Assistent ещё нет');
}
why.push('приоритет: user → session_exact → exact(+persona) → live UI → memory_hits');
const lines = [
'### Debug Assistent',
`persona=${persona} · pack=${pack}`,
`chat=${chatModel} · embed=${embed}`,
`skills=${(state.enabledSkills || []).join(',') || '—'}`,
`auto: apply=${!!$('sa_auto_apply')?.checked} gen=${!!$('sa_auto_generate')?.checked} vision=${!!$('sa_auto_vision')?.checked} critique=${!!$('sa_auto_critique')?.checked}`,
'',
'Live SwarmUI:',
` ckpt=${ctx.checkpoint?.name || '—'} · krea_profile=${ctx.krea_profile || profile}`,
` ${ctx.width || '?'}×${ctx.height || '?'} (${aspect}) · steps=${ctx.steps ?? '—'} · cfg=${ctx.cfg ?? '—'} · sigma=${ctx.sigma_shift ?? '—'} · seed=${ctx.seed ?? '—'} · batch=${ctx.batch ?? '—'}`,
` loras: ${formatDebugLoras(ctx.selected_loras || ctx.enabled_loras)}`,
` prompt: ${clipDebug(ctx.prompt, 220)}`,
` negative: ${clipDebug(ctx.negative, 120)}`,
` init=${!!ctx.has_init_image} mask=${!!ctx.has_mask_image} prompt_images=${ctx.prompt_image_count || 0}`,
'',
'Exact defaults (merged):',
` generation=${JSON.stringify(exactGen)}`,
` effective=${JSON.stringify({
steps: defaults.steps,
cfg: defaults.cfg,
sigma_shift: defaults.sigma_shift,
aspect: defaults.aspect,
images: defaults.images,
profile: defaults.profile,
})}`,
` session_exact=${Object.keys(session).length ? JSON.stringify(session) : '{}'}`,
'',
'Почему так:',
...why.map((w) => ` · ${w}`),
];
if (state.lastPatch) {
lines.push('', `last_patch: ${clipDebug(JSON.stringify(state.lastPatch), 360)}`);
}
return lines.join('\n');
}
async function handleSlashCommand(raw) {
const text = String(raw || '').trim();
if (!text.startsWith('/')) {
@@ -4363,6 +4455,11 @@
setStatus('/help');
return true;
}
if (cmd === 'debug' || cmd === 'dbg' || cmd === 'why') {
appendSystemNote(buildDebugSummary());
setStatus('/debug');
return true;
}
if (cmd === 'gen' || cmd === 'generate') {
const prev = findCurrentGenerateSrc();
startBusyUi('generating');
+2 -1
View File
@@ -1,6 +1,6 @@
{
"welcome_html": "<div class=\"sa-welcome-title\">Assistent · Krea 2</div><ul><li><strong>Generate</strong> слева — живой просмотр. В чат сам не уходит.</li><li><strong>Refs</strong> — референсы на отдельной вкладке: drop / paste / Снимок gen.</li><li>Галочка vision на окне — отправить кадр модели.</li><li>Чипсы aspect / seed / Vary / Turbo·RAW. В чате: <code>/help</code>.</li><li>Кнопки патча только у последнего предложения.</li></ul>Напиши, что сгенерировать — или кинь референс и попроси правку.",
"help_text": "Slash-команды (без LLM):\n/help — этот список\n/gen — Generate сейчас\n/look generate|refN — прикрепить окно к vision\n/init /mask /clear — Init / Mask / Clear Init\n/interrupt — остановить генерацию\n/aspect 16:9 — размер из таблицы 1K\n/seed lock|random — зафиксировать или рандомизировать seed\n/vary — новый seed, тот же промпт\n/pack write|critique|compose|params|inpaint|describe|card\n/civitai <query> — поиск LoRA (Confirm в чате)\n/inventory — rescan моделей + обновить список LoRA\n\nЧипсы над полем ввода делают то же для aspect / seed / vary / Turbo·RAW.",
"help_text": "Slash-команды (без LLM):\n/help — этот список\n/debug — сводка: промпт, params, Exact/session, почему так\n/gen — Generate сейчас\n/look generate|refN — прикрепить окно к vision\n/init /mask /clear — Init / Mask / Clear Init\n/interrupt — остановить генерацию\n/aspect 16:9 — размер из таблицы 1K\n/seed lock|random — зафиксировать или рандомизировать seed\n/vary — новый seed, тот же промпт\n/pack write|critique|compose|params|inpaint|describe|card\n/civitai <query> — поиск LoRA (Confirm в чате)\n/inventory — rescan моделей + обновить список LoRA\n\nЧипсы над полем ввода делают то же для aspect / seed / vary / Turbo·RAW.",
"chips": [
{ "label": "1:1", "action": "aspect", "value": "1:1", "title": "1024×1024" },
{ "label": "4:5", "action": "aspect", "value": "4:5", "title": "928×1152" },
@@ -17,6 +17,7 @@
],
"slash": [
{ "cmd": "/help", "hint": "список команд", "action": "help" },
{ "cmd": "/debug", "hint": "сводка настроек", "action": "debug" },
{ "cmd": "/gen", "hint": "Generate сейчас", "action": "gen" },
{ "cmd": "/look ", "hint": "generate|refN", "action": "look" },
{ "cmd": "/init", "hint": "как Init", "action": "init" },
+1
View File
@@ -51,6 +51,7 @@ Copy `personas/cinema/` → `noir/`, edit only differing JSON files.
| Command | Effect |
| --- | --- |
| `/help` | List commands |
| `/debug` | Short dump: prompt, params, Exact/session, why |
| `/gen` | Generate now |
| `/look generate\|refN` | Attach that board window + ask the LLM to look |
| `/init` `/mask` `/clear` | Same as board buttons |