feat: AI assistant (MVP) - chat button per user, sees the workspace, streams answers, runs suggested commands in the active terminal; Gradio, OpenAI and Anthropic models set in Настройки

This commit is contained in:
redtea committed 2026-10-15 22:10:47 +03:00
1 parent 9572a35ad5
commit 46948f5ddc
9 files changed
+811

No files matched your search

+10
View File
@@ -41,6 +41,8 @@
' <p class="acct-msg"></p>' +
' <label class="acct-pw"><span><b>Вход по паролю</b><small class="muted acct-pwnote"></small></span>' +
' <input type="checkbox" class="sw" role="switch"></label>' +
' <label class="acct-pw acct-ai"><span><b>ИИ-ассистент</b><small class="muted">кнопка чата в правом нижнем углу</small></span>' +
' <input type="checkbox" class="sw" role="switch"></label>' +
' <details class="acct-chpw"><summary>Сменить пароль</summary>' +
' <form class="acct-pwform" autocomplete="on">' +
' <input type="text" name="username" autocomplete="username" hidden>' +
@@ -191,6 +193,14 @@
$('.acct-pindel').onclick = function () {
if (confirm('Убрать PIN-код?')) savePin('');
};
// The assistant: each user's own switch; the chat button follows it.
fetch('/api/panel/ai', {cache: 'no-store'}).then(function (r) { return r.json(); }).then(function (d) { $('.acct-ai .sw').checked = !!d.on; }).catch(function () {});
$('.acct-ai .sw').onchange = function (ev) {
var on = ev.target.checked;
fetch('/api/panel/ai/toggle', {method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({on: on})})
.then(function (r) { return r.json(); })
.then(function (r) { if (!r.ok) { ev.target.checked = !on; msg(r.error, true); } else document.dispatchEvent(new CustomEvent('lpra:ai', {detail: on})); });
};
$('.acct-pw .sw').onchange = function (ev) {
const off = !ev.target.checked;
if (off && !confirm('Выключить вход по паролю? Войти можно будет только ключом доступа. Если ключи потеряются, их сможет сбросить другой администратор в «Настройках».')) {