kingkont 0.14.3 → 0.14.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/renderer/chat.js +49 -4
- package/renderer/styles.css +11 -0
package/package.json
CHANGED
package/renderer/chat.js
CHANGED
|
@@ -209,6 +209,17 @@
|
|
|
209
209
|
},
|
|
210
210
|
},
|
|
211
211
|
|
|
212
|
+
take_snapshot: {
|
|
213
|
+
description: 'Сделать снимок проекта ДО серьёзного изменения (удаление, массовое редактирование промптов, очистка таймлайна, перезапуск генерации). Юзер потом может откатить через UI tool-блока в чате. Label — короткое описание что собираешься делать («перед удалением 3 нод», «перед очисткой timeline»). НЕ делай snapshot перед read-only действиями (read_scene, list_scenes) — только перед destructive.',
|
|
214
|
+
params: '{"label":"<короткое описание что будет сделано>"}',
|
|
215
|
+
async handler({ label }) {
|
|
216
|
+
const snap = await takeSnapshot(label || 'без метки');
|
|
217
|
+
if (!snap) throw new Error('не удалось сделать snapshot (нет filmHandle?)');
|
|
218
|
+
const idx = snapshots.indexOf(snap);
|
|
219
|
+
return { ok: true, snapshotIdx: idx, label: snap.label, ts: snap.ts };
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
|
|
212
223
|
delete_node: {
|
|
213
224
|
description: 'Удалить ноду. Файл (если есть) переедет в _deleted/.',
|
|
214
225
|
params: '{"id":"<node-id>"}',
|
|
@@ -421,6 +432,13 @@
|
|
|
421
432
|
lines.push('- Не выдумывай имена сцен — сначала list_scenes.');
|
|
422
433
|
lines.push('- Для генерации сразу после add_node — ВОЗЬМИ id из result.id ПРЕДЫДУЩЕГО вызова и передай в generate_node.');
|
|
423
434
|
lines.push('- Когда нужно создать несколько нод сразу — выдавай add_node + generate_node чередуя, или сначала все add_node, потом все generate_node (используя id из их result-ов).');
|
|
435
|
+
lines.push('');
|
|
436
|
+
lines.push('SNAPSHOT для отката (важно):');
|
|
437
|
+
lines.push('- Перед DESTRUCTIVE действиями (delete_node, update_node_prompt, generate_node на ноду которая уже сгенерирована, clear_timeline, remove_clip_from_timeline) — позови take_snapshot ПЕРВЫМ tool в этом турне.');
|
|
438
|
+
lines.push('- Label snapshot\'a — короткое описание того что сейчас делаешь («перед удалением 3 нод», «перед перегенерацией картинки Закат», «перед очисткой таймлайна»).');
|
|
439
|
+
lines.push('- НЕ зови take_snapshot для read-only действий (read_scene, list_scenes, list_timeline) и для безопасных операций добавления (add_node без перетирания, add_clip_to_timeline).');
|
|
440
|
+
lines.push('- Если в одном турне НЕСКОЛЬКО destructive-вызовов — одного take_snapshot в начале достаточно.');
|
|
441
|
+
lines.push('');
|
|
424
442
|
lines.push('- Отвечай по-русски, кратко. Объясняй что делаешь, без лишней воды.');
|
|
425
443
|
lines.push('');
|
|
426
444
|
lines.push('ВАЖНО: НИКОГДА не пиши <tool_result>...</tool_result> сам — это формат который Я');
|
|
@@ -703,8 +721,13 @@
|
|
|
703
721
|
}
|
|
704
722
|
|
|
705
723
|
function renderSnapshotBar() {
|
|
724
|
+
// Snapshot-bar отключён — откаты теперь inline в chat tool-блоке.
|
|
725
|
+
// (Кнопка ↩ Откатить «label» под каждым take_snapshot tool'ом.)
|
|
706
726
|
const bar = $('chatSnapshotBar');
|
|
707
727
|
if (!bar) return;
|
|
728
|
+
bar.style.display = 'none';
|
|
729
|
+
return;
|
|
730
|
+
// -- legacy code below, не выполняется --
|
|
708
731
|
bar.innerHTML = '';
|
|
709
732
|
if (!snapshots.length) { bar.style.display = 'none'; return; }
|
|
710
733
|
bar.style.display = '';
|
|
@@ -1089,10 +1112,8 @@
|
|
|
1089
1112
|
if (!userText.trim()) return;
|
|
1090
1113
|
const key = sessionKey();
|
|
1091
1114
|
if (!key) { alert('Сначала открой проект'); return; }
|
|
1092
|
-
// Snapshot
|
|
1093
|
-
|
|
1094
|
-
await takeSnapshot(userText.length > 60 ? userText.slice(0, 60) + '…' : userText);
|
|
1095
|
-
} catch (e) { console.warn('snapshot failed:', e?.message); }
|
|
1115
|
+
// Snapshot НЕ берём автоматически — теперь это явный tool take_snapshot,
|
|
1116
|
+
// который Claude вызывает перед destructive-действиями. См. system-prompt.
|
|
1096
1117
|
// Контекст + system-prompt: формируем тут (на клиенте) и отдаём серверу.
|
|
1097
1118
|
const ctxSnap = buildContextSnapshot();
|
|
1098
1119
|
const system = buildSystemPrompt() + '\n\n' + buildContextBlock(ctxSnap);
|
|
@@ -1190,6 +1211,30 @@
|
|
|
1190
1211
|
const pre = document.createElement('pre');
|
|
1191
1212
|
pre.textContent = JSON.stringify(dumpAll, null, 2);
|
|
1192
1213
|
t.appendChild(pre);
|
|
1214
|
+
// Если среди tools есть take_snapshot — добавляем кнопки отката.
|
|
1215
|
+
// Pattern: одна кнопка ↩ на каждый snapshot tool-call. snapshotIdx
|
|
1216
|
+
// приходит из result handler'а (см. take_snapshot tool).
|
|
1217
|
+
for (const tc of m.tools) {
|
|
1218
|
+
if (tc.name !== 'take_snapshot' || !tc._ok || tc._error) continue;
|
|
1219
|
+
const idx = tc.result?.snapshotIdx;
|
|
1220
|
+
const lbl = tc.result?.label || tc.args?.label || '';
|
|
1221
|
+
if (typeof idx !== 'number') continue;
|
|
1222
|
+
const rb = document.createElement('button');
|
|
1223
|
+
rb.className = 'chat-snapshot-rollback';
|
|
1224
|
+
rb.textContent = `↩ Откатить «${lbl}»`;
|
|
1225
|
+
rb.title = `Откат до snapshot'а #${idx}`;
|
|
1226
|
+
rb.addEventListener('click', () => {
|
|
1227
|
+
// snapshots могли уже измениться (новые добавились) — find by ts.
|
|
1228
|
+
const realIdx = snapshots.findIndex(s => s.ts === tc.result?.ts);
|
|
1229
|
+
if (realIdx < 0) {
|
|
1230
|
+
alert('Snapshot потерялся (возможно вы переключили проект).');
|
|
1231
|
+
return;
|
|
1232
|
+
}
|
|
1233
|
+
if (!confirm(`Откатить до «${lbl}»?`)) return;
|
|
1234
|
+
rollbackToSnapshot(realIdx);
|
|
1235
|
+
});
|
|
1236
|
+
div.appendChild(rb);
|
|
1237
|
+
}
|
|
1193
1238
|
div.appendChild(t);
|
|
1194
1239
|
}
|
|
1195
1240
|
list.appendChild(div);
|
package/renderer/styles.css
CHANGED
|
@@ -300,6 +300,17 @@
|
|
|
300
300
|
border-radius: 4px; padding: 2px 8px; cursor: pointer; font-size: 12px;
|
|
301
301
|
}
|
|
302
302
|
.chat-header button:hover { background: #2a2a2a; color: #fff; }
|
|
303
|
+
/* Кнопка отката снепшота прямо в чат-сообщении (под take_snapshot tool). */
|
|
304
|
+
.chat-snapshot-rollback {
|
|
305
|
+
margin-top: 4px; align-self: flex-start;
|
|
306
|
+
background: #232a36; border: 1px solid #3a4a5a; color: #aac;
|
|
307
|
+
font-size: 11px; padding: 3px 8px; border-radius: 999px;
|
|
308
|
+
cursor: pointer; opacity: 0.85;
|
|
309
|
+
}
|
|
310
|
+
.chat-snapshot-rollback:hover {
|
|
311
|
+
background: #2a3548; border-color: #4a6a8a; color: #cde; opacity: 1;
|
|
312
|
+
}
|
|
313
|
+
|
|
303
314
|
.chat-snapshot-bar {
|
|
304
315
|
padding: 6px 10px; background: #1f1f1f; border-bottom: 1px solid #2a2a2a;
|
|
305
316
|
display: flex; align-items: center; gap: 6px; flex-shrink: 0;
|