mirror of
https://github.com/wasrusgen/zashita-brandbook.git
synced 2026-06-03 21:24:47 +00:00
feat: Elena action buttons after each response
This commit is contained in:
parent
82395cbba1
commit
33d9ec4185
68
mockup.html
68
mockup.html
@ -4575,6 +4575,55 @@ function _buildElenaContext() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Парсит [ДЕЙСТВИЯ: ...] из ответа Елены и возвращает {text, actions[]}
|
||||||
|
function _parseElenaActions(reply) {
|
||||||
|
if (!reply) return { text: reply, actions: [] };
|
||||||
|
var match = reply.match(/\[ДЕЙСТВИЯ:\s*([^\]]+)\]/);
|
||||||
|
if (!match) return { text: reply, actions: [] };
|
||||||
|
var text = reply.replace(match[0], '').trim();
|
||||||
|
var actions = match[1].split('·').map(function(a){ return a.trim(); }).filter(Boolean);
|
||||||
|
return { text: text, actions: actions };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Определяет что делать по клику на кнопку действия
|
||||||
|
function _elenaActionClick(label) {
|
||||||
|
var l = label.toLowerCase();
|
||||||
|
if (/уведомлени|составить|претензи|подготовить/.test(l)) {
|
||||||
|
// Переходим к созданию документа
|
||||||
|
var up = document.getElementById('el-step-upload');
|
||||||
|
if (up) { up.style.display = ''; up.scrollIntoView({behavior:'smooth'}); }
|
||||||
|
else { go('elena'); setTimeout(function(){ elenaIntent('create'); }, 80); }
|
||||||
|
} else if (/кабинет|зафиксировать/.test(l)) {
|
||||||
|
go('cabinet'); tab('sroki');
|
||||||
|
} else if (/напоминани/.test(l)) {
|
||||||
|
go('cabinet'); tab('sroki');
|
||||||
|
} else if (/проверить договор/.test(l)) {
|
||||||
|
var up2 = document.getElementById('el-step-upload');
|
||||||
|
if (up2) { up2.style.display = ''; up2.scrollIntoView({behavior:'smooth'}); }
|
||||||
|
else { go('elena'); setTimeout(function(){ elenaIntent('check'); }, 80); }
|
||||||
|
} else {
|
||||||
|
// Уточнить детали — фокус на input
|
||||||
|
var inp = document.getElementById('el-continue-input') || document.getElementById('intake-custom');
|
||||||
|
if (inp) { var i = inp.tagName === 'INPUT' ? inp : inp.querySelector('input'); if (i) i.focus(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Рисует кнопки действий после пузыря Елены
|
||||||
|
function _renderElenaActions(actions, container) {
|
||||||
|
if (!actions || !actions.length) return;
|
||||||
|
var bar = document.createElement('div');
|
||||||
|
bar.style.cssText = 'display:flex;gap:8px;flex-wrap:wrap;margin:8px 0 0 51px';
|
||||||
|
actions.forEach(function(label) {
|
||||||
|
var btn = document.createElement('button');
|
||||||
|
btn.className = 'svc-btn-detail';
|
||||||
|
btn.style.cssText = 'font-size:13px;padding:7px 14px';
|
||||||
|
btn.textContent = label;
|
||||||
|
btn.onclick = function(){ _elenaActionClick(label); };
|
||||||
|
bar.appendChild(btn);
|
||||||
|
});
|
||||||
|
container.appendChild(bar);
|
||||||
|
}
|
||||||
|
|
||||||
function _elenaApi(txt, intent, callback) {
|
function _elenaApi(txt, intent, callback) {
|
||||||
/* Вызывает /api/elena. При ошибке — fallback на шаблон. */
|
/* Вызывает /api/elena. При ошибке — fallback на шаблон. */
|
||||||
if (!_apiAvailable) { callback(null); return; }
|
if (!_apiAvailable) { callback(null); return; }
|
||||||
@ -4595,14 +4644,17 @@ function _elenaApi(txt, intent, callback) {
|
|||||||
.then(function(r){ return r.json(); })
|
.then(function(r){ return r.json(); })
|
||||||
.then(function(d){
|
.then(function(d){
|
||||||
if (d.reply) {
|
if (d.reply) {
|
||||||
|
var parsed = _parseElenaActions(d.reply);
|
||||||
_chatHistory.push({role:'user', content: txt});
|
_chatHistory.push({role:'user', content: txt});
|
||||||
_chatHistory.push({role:'assistant', content: d.reply});
|
_chatHistory.push({role:'assistant', content: parsed.text});
|
||||||
callback(d.reply);
|
// Передаём в callback объект {text, actions} — совместимо со старым кодом
|
||||||
|
// (старый код ожидает строку — если передать строку, ничего не сломается)
|
||||||
|
callback(parsed.text, parsed.actions);
|
||||||
} else {
|
} else {
|
||||||
callback(null);
|
callback(null, []);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function(){ callback(null); });
|
.catch(function(){ callback(null, []); });
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── КЛАССИФИКАТОР ВХОДЯЩИХ СООБЩЕНИЙ ── */
|
/* ── КЛАССИФИКАТОР ВХОДЯЩИХ СООБЩЕНИЙ ── */
|
||||||
@ -5349,7 +5401,7 @@ function _rcTransferToElena(intent) {
|
|||||||
|
|
||||||
// Реальный ответ через API или шаблон
|
// Реальный ответ через API или шаблон
|
||||||
var fallbackReply = _getElenaCtxReply(intent, dl);
|
var fallbackReply = _getElenaCtxReply(intent, dl);
|
||||||
_elenaApi(contextMsg, intent, function(apiReply){
|
_elenaApi(contextMsg, intent, function(apiReply, apiActions){
|
||||||
var t = document.getElementById('elena-ctx-typing');
|
var t = document.getElementById('elena-ctx-typing');
|
||||||
if (t) t.remove();
|
if (t) t.remove();
|
||||||
var reply = apiReply || fallbackReply;
|
var reply = apiReply || fallbackReply;
|
||||||
@ -5359,6 +5411,7 @@ function _rcTransferToElena(intent) {
|
|||||||
eDiv.innerHTML = '<div class="av"><img src="logos/elena-photo.jpg"></div>' +
|
eDiv.innerHTML = '<div class="av"><img src="logos/elena-photo.jpg"></div>' +
|
||||||
'<div class="bubble"><div class="nm">Елена</div>' + _rcEscape(reply) + '</div>';
|
'<div class="bubble"><div class="nm">Елена</div>' + _rcEscape(reply) + '</div>';
|
||||||
wrap.appendChild(eDiv);
|
wrap.appendChild(eDiv);
|
||||||
|
if (apiActions && apiActions.length) _renderElenaActions(apiActions, wrap);
|
||||||
wrap.scrollTop = wrap.scrollHeight;
|
wrap.scrollTop = wrap.scrollHeight;
|
||||||
|
|
||||||
// Показываем поле ввода Елены.
|
// Показываем поле ввода Елены.
|
||||||
@ -5416,7 +5469,7 @@ function _elenaContinueSend() {
|
|||||||
if (cont) cont.remove();
|
if (cont) cont.remove();
|
||||||
// Елена отвечает
|
// Елена отвечает
|
||||||
_hcAddTyping();
|
_hcAddTyping();
|
||||||
_elenaApi(txt, 'create', function(apiReply) {
|
_elenaApi(txt, 'create', function(apiReply, apiActions) {
|
||||||
_hcRemoveTyping();
|
_hcRemoveTyping();
|
||||||
var reply = apiReply || 'Уточните, пожалуйста, детали документа.';
|
var reply = apiReply || 'Уточните, пожалуйста, детали документа.';
|
||||||
_chatHistory.push({role:'user', content: txt});
|
_chatHistory.push({role:'user', content: txt});
|
||||||
@ -5426,8 +5479,9 @@ function _elenaContinueSend() {
|
|||||||
eDiv.innerHTML = '<div class="av"><img src="logos/elena-photo.jpg"></div>'
|
eDiv.innerHTML = '<div class="av"><img src="logos/elena-photo.jpg"></div>'
|
||||||
+ '<div class="bubble"><div class="nm">Елена</div>' + _rcEscape(reply) + '</div>';
|
+ '<div class="bubble"><div class="nm">Елена</div>' + _rcEscape(reply) + '</div>';
|
||||||
wrap.appendChild(eDiv);
|
wrap.appendChild(eDiv);
|
||||||
|
if (apiActions && apiActions.length) _renderElenaActions(apiActions, wrap);
|
||||||
wrap.scrollTop = wrap.scrollHeight;
|
wrap.scrollTop = wrap.scrollHeight;
|
||||||
_elenaShowInput(); // снова показываем поле для следующего ответа
|
_elenaShowInput();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user