feat: the assistant's chat - the name clear of the close button, typing dots while the model starts, thinking that opens without reflow; asking before a command: «Выполнить команду на [машина]?», the command in mono, a red «Отмена»

This commit is contained in:
redtea committed 2026-10-16 10:48:05 +03:00
1 parent 3641a3627c
commit fcf9417f5a
3 files changed
+55 -10

No files matched your search

+13 -5
View File
@@ -356,10 +356,16 @@
}
// ask first for what changes something: commands and writes.
function needsYes(a) { return a.kind === 'run' || a.kind === 'write'; }
function describe(a) {
const where = a.machine ? a.machine + ': ' : '';
return a.kind === 'run' ? 'Выполнить на ' + (a.machine || 'активной машине') + ':\n\n' + a.body
: 'Записать файл ' + where + a.path + ' (' + a.body.length + ' символов)?';
// ask what a command or a write is about to do: what, where, the command
// (or the start of the text) in mono.
function confirmAction(a) {
const m = machineOf(a.machine), where = m ? m.name : (a.machine || 'активная машина');
if (a.kind === 'run') return UI.confirm('Выполнить команду на {chip}?', {ok: 'Выполнить', chip: where, code: a.body,
note: 'Уйдёт в терминал этой машины с вашими правами.'});
const lines = a.body.split('\n');
return UI.confirm('Записать файл {chip}?', {ok: 'Записать', chip: where + ':' + a.path,
code: lines.slice(0, 12).join('\n') + (lines.length > 12 ? '\n…' : ''),
note: 'Файл будет заменён целиком (' + a.body.length + ' символов).'});
}
// ---------- messages ----------
@@ -463,6 +469,8 @@
if (res) showResult(res);
const el = add('assistant', '');
el.classList.add('wait');
// While the model starts: a typing mark, gone with the first words.
el.querySelector('.ai-body').innerHTML = '<span class="ai-typing" aria-label="печатает"><i></i><i></i><i></i></span>';
ac = new AbortController();
send.innerHTML = STOP; send.title = 'Остановить';
let answer = '';
@@ -521,7 +529,7 @@
// Without «Агент» only searches go on by themselves, with «Поиск» on.
if (!agentOn() && !(a.kind === 'search' && searchOn())) break;
const b = turn.el.querySelector('.ai-act');
if (needsYes(a) && !await UI.confirm(describe(a), {ok: a.kind === 'run' ? 'Выполнить' : 'Записать'})) {
if (needsYes(a) && !await confirmAction(a)) {
if (b) { b.disabled = true; b.textContent = 'Отклонено'; }
turn = await ask(null, 'Пользователь отклонил это действие. Предложи другое или закончи.');
continue;