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

@@ -1360,36 +1360,55 @@ def auto_match_item_vehicles(item_id):
part_number, brand, name = row
compat_source = get_compat_source(g.tenant_id)
tecdoc_result = None
qwen_result = None
# TecDoc auto-match
if compat_source in ('tecdoc', 'both'):
master = get_master_conn()
try:
result = auto_match_vehicle_compatibility(master, conn, item_id, part_number,
brand=brand, name=name)
return jsonify(result)
tecdoc_result = auto_match_vehicle_compatibility(master, conn, item_id, part_number,
brand=brand, name=name)
finally:
master.close()
conn.close()
# QWEN AI auto-match
if compat_source == 'qwen':
if compat_source in ('qwen', 'both'):
try:
from services.qwen_fitment import get_vehicle_fitment
from services.inventory_vehicle_compat import save_qwen_fitment
fitment = get_vehicle_fitment(part_number, name, brand)
inserted = save_qwen_fitment(conn, item_id, fitment)
conn.close()
return jsonify({
'matched': inserted > 0,
qwen_myes = [v['mye_id'] for v in fitment.get('vehicles', []) if v.get('mye_id')]
qwen_result = {
'matched': len(qwen_myes) > 0,
'matches': [],
'myes': [v['mye_id'] for v in fitment.get('vehicles', []) if v.get('mye_id')],
'myes': qwen_myes,
'inserted': inserted,
})
'total_qwen': len(qwen_myes),
'confidence': fitment.get('confidence', 0),
'notes': fitment.get('notes', ''),
}
except Exception as e:
conn.close()
return jsonify({'error': str(e)}), 500
qwen_result = {'error': str(e)}
conn.close()
# Return combined or single-source result
if compat_source == 'both':
return jsonify({
'tecdoc': tecdoc_result,
'qwen': qwen_result,
'matched': bool(
(tecdoc_result and tecdoc_result.get('matched'))
or (qwen_result and qwen_result.get('matched'))
),
})
if compat_source == 'tecdoc':
return jsonify(tecdoc_result)
if compat_source == 'qwen':
return jsonify(qwen_result)
return jsonify({'error': 'No compatibility source configured'}), 400