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');