feat(whatsapp): QWEN primary AI backend, Hermes fallback, conversation history, vehicle persistence, demo prompts
- Add QWEN (qwen3.6) as primary AI backend with short system prompt - Hermes remains as fallback with 45s timeout - Increase QWEN timeout to 35s, max_tokens to 4000 - Add conversation history loading from whatsapp_messages (last 4 msgs) - Persist detected vehicle in whatsapp_sessions table - Add 'limpiar chat' / 'nuevo chat' / 'reset' commands to clear history - Fix CSS conflict: rename whatsapp chat-panel classes to wa-chat-panel - Fix JS ID conflicts with chat.js widget (waChatPanel, waChatMessages, etc.) - Improve no-stock response: conversational with alternatives - Split search_query by | for multi-part lookups - Add DEMO_PROMPTS.md and DEMO_PROMPTS_V2.md
This commit is contained in:
@@ -65,13 +65,13 @@
|
||||
// -- DOM refs --------------------------------------------------------------
|
||||
|
||||
var convList = document.getElementById('convList');
|
||||
var chatMessages = document.getElementById('chatMessages');
|
||||
var chatMessages = document.getElementById('waChatMessages') || document.getElementById('chatMessages');
|
||||
var chatHeader = document.getElementById('chatHeaderPhone');
|
||||
var chatInput = document.getElementById('chatInput');
|
||||
var sendBtn = document.getElementById('sendBtn');
|
||||
var chatInput = document.getElementById('waChatInput') || document.getElementById('chatInput');
|
||||
var sendBtn = document.getElementById('waSendBtn') || document.getElementById('sendBtn');
|
||||
var newChatBtn = document.getElementById('newChatBtn');
|
||||
var emptyState = document.getElementById('emptyState');
|
||||
var chatPanel = document.getElementById('chatPanel');
|
||||
var chatPanel = document.getElementById('waChatPanel') || document.getElementById('chatPanel');
|
||||
var statusDot = document.getElementById('statusDot');
|
||||
var statusText = document.getElementById('statusText');
|
||||
var connectSection = document.getElementById('connectSection');
|
||||
@@ -275,6 +275,7 @@
|
||||
activePhone = null;
|
||||
chatPanel.style.display = 'none';
|
||||
emptyState.style.display = '';
|
||||
if (messengerArea) messengerArea.classList.remove('has-active-chat');
|
||||
}
|
||||
loadConversations();
|
||||
} else {
|
||||
@@ -300,42 +301,65 @@
|
||||
var activeContactName = '';
|
||||
|
||||
function openConversation(phone, contactName) {
|
||||
activePhone = phone;
|
||||
// Use contact name if available; fall back to formatted phone
|
||||
var isLid = phone.length > 13 || !/^(52|1|44|34)/.test(phone);
|
||||
activeContactName = contactName || '';
|
||||
chatHeader.textContent = activeContactName || (isLid ? 'Contacto WhatsApp' : fmtPhone(phone));
|
||||
emptyState.style.display = 'none';
|
||||
chatPanel.style.display = 'flex';
|
||||
try {
|
||||
console.log('[WA-UI] Opening conversation:', phone, contactName);
|
||||
activePhone = phone;
|
||||
// Use contact name if available; fall back to formatted phone
|
||||
var isLid = phone.length > 13 || !/^(52|1|44|34)/.test(phone);
|
||||
activeContactName = contactName || '';
|
||||
chatHeader.textContent = activeContactName || (isLid ? 'Contacto WhatsApp' : fmtPhone(phone));
|
||||
emptyState.style.display = 'none';
|
||||
chatPanel.style.display = 'flex';
|
||||
console.log('[WA-UI] chatPanel display set to flex. chatPanel element:', chatPanel ? 'exists' : 'null');
|
||||
// Add has-active-chat class for mobile responsive layout
|
||||
if (messengerArea) messengerArea.classList.add('has-active-chat');
|
||||
|
||||
convList.querySelectorAll('.conv-item').forEach(function (el) {
|
||||
el.classList.toggle('is-active', el.getAttribute('data-phone') === phone);
|
||||
});
|
||||
convList.querySelectorAll('.conv-item').forEach(function (el) {
|
||||
el.classList.toggle('is-active', el.getAttribute('data-phone') === phone);
|
||||
});
|
||||
|
||||
loadMessages(phone);
|
||||
startPolling();
|
||||
loadMessages(phone);
|
||||
startPolling();
|
||||
} catch (e) {
|
||||
console.error('[WA-UI] openConversation error:', e);
|
||||
}
|
||||
}
|
||||
|
||||
function loadMessages(phone) {
|
||||
console.log('[WA-UI] loadMessages start:', phone);
|
||||
api('GET', '/conversations/' + encodeURIComponent(phone)).then(function (data) {
|
||||
console.log('[WA-UI] loadMessages response:', data);
|
||||
if (data.error) {
|
||||
console.error('[WA-UI] loadMessages error:', data.error);
|
||||
chatMessages.innerHTML = '<div class="chat-empty">Error cargando mensajes: ' + escHtml(data.error) + '</div>';
|
||||
return;
|
||||
}
|
||||
var msgs = data.messages || [];
|
||||
console.log('[WA-UI] loadMessages messages count:', msgs.length);
|
||||
renderMessages(msgs);
|
||||
}).catch(function (err) {
|
||||
console.error('[WA-UI] loadMessages network error:', err);
|
||||
chatMessages.innerHTML = '<div class="chat-empty">Error de red al cargar mensajes</div>';
|
||||
});
|
||||
}
|
||||
|
||||
function renderMessages(msgs) {
|
||||
console.log('[WA-UI] renderMessages called with', msgs.length, 'messages');
|
||||
if (!chatMessages) {
|
||||
console.error('[WA-UI] chatMessages element is null!');
|
||||
return;
|
||||
}
|
||||
var html = '';
|
||||
msgs.forEach(function (m) {
|
||||
var cls = m.direction === 'outgoing' ? 'msg-bubble--out' : 'msg-bubble--in';
|
||||
// Support both 'text' and 'message_text' keys (backend changed)
|
||||
var text = m.message_text || m.text || '';
|
||||
// Support both 'created_at' and 'date' keys
|
||||
var time = m.created_at || m.date || '';
|
||||
html += '<div class="msg-bubble ' + cls + '">'
|
||||
+ '<div class="msg-bubble__text">' + escHtml(text).replace(/\n/g, '<br>') + '</div>'
|
||||
+ '<div class="msg-bubble__meta">' + fmtTime(time) + '</div>'
|
||||
+ '</div>';
|
||||
});
|
||||
console.log('[WA-UI] renderMessages HTML length:', html.length);
|
||||
chatMessages.innerHTML = html || '<div class="chat-empty">Sin mensajes</div>';
|
||||
chatMessages.scrollTop = chatMessages.scrollHeight;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user