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:
2026-05-06 20:27:14 +00:00
parent 371d72887e
commit ff45905b49
33 changed files with 3040 additions and 445 deletions

View File

@@ -114,7 +114,12 @@
html += '<div style="font-size:var(--text-h5);font-weight:700;color:var(--color-text-accent);">Total: $' + fmt(q.total) + '</div>';
html += '</div>';
html += '<div style="margin-top:var(--space-5);display:flex;gap:var(--space-3);justify-content:flex-end;">';
html += '<div style="margin-top:var(--space-5);display:flex;gap:var(--space-3);justify-content:flex-end;flex-wrap:wrap;">';
if (q.status === 'active') {
html += '<button class="btn btn--ghost" onclick="editQuote(' + q.id + ')" style="color:#4f46e5;">Editar</button>';
html += '<button class="btn btn--ghost" onclick="convertQuote(' + q.id + ')" style="color:#059669;">Convertir a venta</button>';
html += '<button class="btn btn--ghost" onclick="shareQuote(' + q.id + ')">Compartir link</button>';
}
html += '<button class="btn btn--ghost" onclick="deleteQuote(' + q.id + ')" style="color:#F85149;">Eliminar</button>';
html += '<button class="btn btn--ghost" onclick="exportVisibleTableCSV(\'cotizacion_' + q.id + '\')">Exportar CSV</button>';
html += '<button class="btn btn--ghost" onclick="window.print()">Imprimir</button>';
@@ -140,6 +145,68 @@
});
};
window.editQuote = function(id) {
fetch(API + '/quotations/' + id, { headers: headers() })
.then(function(r) { return r.json(); })
.then(function(q) {
if (!q.items) { alert('Error cargando cotización'); return; }
var cartItems = q.items.map(function(it) {
return {
inventory_id: it.inventory_id,
part_number: it.part_number,
name: it.name,
quantity: it.quantity,
unit_price: it.unit_price,
discount_pct: it.discount_pct,
tax_rate: it.tax_rate
};
});
localStorage.setItem('pos_edit_quote_id', id);
localStorage.setItem('pos_edit_quote_customer_id', q.customer_id || '');
localStorage.setItem('pos_edit_quote_notes', q.notes || '');
localStorage.setItem('pos_cart', JSON.stringify(cartItems));
window.location.href = '/pos';
});
};
window.convertQuote = function(id) {
fetch(API + '/quotations/' + id, { headers: headers() })
.then(function(r) { return r.json(); })
.then(function(q) {
if (!q.items) { alert('Error cargando cotización'); return; }
var cartItems = q.items.map(function(it) {
return {
inventory_id: it.inventory_id,
part_number: it.part_number,
name: it.name,
quantity: it.quantity,
unit_price: it.unit_price,
discount_pct: it.discount_pct,
tax_rate: it.tax_rate
};
});
localStorage.setItem('pos_convert_quote_id', id);
localStorage.setItem('pos_cart', JSON.stringify(cartItems));
window.location.href = '/pos';
});
};
window.shareQuote = function(id) {
fetch(API + '/quotations/' + id + '/share', { method: 'POST', headers: headers() })
.then(function(r) { return r.json(); })
.then(function(d) {
if (d.url) {
navigator.clipboard.writeText(d.url).then(function() {
alert('Link copiado al portapapeles:\n' + d.url);
}).catch(function() {
prompt('Copia este link:', d.url);
});
} else {
alert('Error: ' + (d.error || 'desconocido'));
}
});
};
// Close modal on outside click
document.getElementById('quoteModal').addEventListener('click', function(e) {
if (e.target === this) this.classList.remove('open');