feat: Aussteller-Suche für SPIEL Essen — 1015 Verlage in DB + Chatbot-Integration

- Neue Tabelle 'aussteller' mit 1015 Ausstellern von spiel-essen.de
- Chatbot /api/chat durchsucht jetzt Aussteller + Community-Beiträge
- Keyword-Scoring für relevante Treffer (bis 40 bei Hallen-Fragen)
- System-Prompt um Aussteller-Kontext erweitert
- getestet: Pegasus, Kosmos, Halle-3-Suche, Unbekannt-Fallback
This commit is contained in:
Hermes Agent
2026-06-18 14:41:40 +02:00
parent 7c96743237
commit ced5604799
+47 -6
View File
@@ -3086,16 +3086,13 @@ def api_chat():
"SELECT id, halle, content, summary, type, sender_name, category, "
"spiel_titel, published_at "
"FROM submissions WHERE status='published' AND deleted_at IS NULL "
"ORDER BY published_at DESC LIMIT 60"
"ORDER BY published_at DESC LIMIT 40"
).fetchall()
if not rows:
return jsonify({'reply': 'Noch keine Beiträge veröffentlicht. Schau später wieder vorbei!'})
# Build compact context string
context_parts = []
for i, r in enumerate(rows, 1):
text = (r['summary'] or r['content'] or '').strip()[:400]
text = (r['summary'] or r['content'] or '').strip()[:300]
halle = r['halle'] or ''
spiel = r['spiel_titel'] or ''
cat = r['category'] or ''
@@ -3107,6 +3104,49 @@ def api_chat():
+ (f" | #{cat}" if cat else '')
+ (f" | von {name}" if name else '')
)
# Also search aussteller table for matching exhibitors
search_terms = user_message.lower().split()
aussteller_rows = []
try:
aussteller_rows = db.execute(
"SELECT name, halle, stand, land, info, web, themen FROM aussteller LIMIT 1015"
).fetchall()
except Exception:
aussteller_rows = []
if aussteller_rows:
# Score and filter exhibitors by keyword match
scored = []
for a in aussteller_rows:
full_text = f"{a['name'] or ''} {a['halle'] or ''} {a['stand'] or ''} {a['land'] or ''} {a['info'] or ''} {a['themen'] or ''}".lower()
score = sum(1 for t in search_terms if t in full_text)
if score > 0:
scored.append((score, a))
scored.sort(key=lambda x: -x[0])
# Add top matching exhibitors
for _, a in scored[:20]:
halle_stand = f"{a['halle'] or ''} {a['stand'] or ''}".strip()
land = a['land'] or ''
info = (a['info'] or '').strip()[:150]
web = a['web'] or ''
context_parts.append(
f"[Aussteller] {a['name']}"
+ (f" | {halle_stand}" if halle_stand else '')
+ (f" | {land}" if land else '')
+ (f" | {info}" if info else '')
+ (f" | Web: {web}" if web else '')
)
# Also include all exhibitors matching the user's search when they ask about halls/stands
if any(t in user_message.lower() for t in ['halle', 'stand', 'aussteller', 'verlag', 'verlage', 'publisher', 'spiel']):
for _, a in scored[:40]:
halle_stand = f"{a['halle'] or ''} {a['stand'] or ''}".strip()
land = a['land'] or ''
context_parts.append(
f"[Aussteller] {a['name']}"
+ (f" | {halle_stand}" if halle_stand else '')
+ (f" | {land}" if land else '')
)
context = '\n'.join(context_parts)
# System prompt
@@ -3120,11 +3160,12 @@ def api_chat():
"- Antworte immer auf Deutsch, freundlich und hilfsbereit.\n"
"- Halte Antworten kurz und präzise (2-4 Sätze).\n"
"- Bei Standortfragen nenne immer die Hallen-Nummer.\n"
"- [Aussteller]-Einträge enthalten Verlage/Shops mit Halle, Stand und Land.\n"
"- Wenn du einen Beitrag erwähnst, verlinke ihn IMMER mit der Beitrags-ID aus dem Kontext.\n"
" Format: [Kurzbeschreibung](/beitrag/ID)\n"
" Beispiel: 'Schau dir [diesen Erfahrungsbericht](/beitrag/53) an!'\n"
" Nutze die Nummer aus 'Beitrag #ID' im Kontext als Linkziel.\n\n"
f"KONTEXT (veröffentlichte Community-Beiträge):\n{context[:8000]}"
f"KONTEXT (veröffentlichte Community-Beiträge + SPIEL Essen Aussteller):\n{context[:10000]}"
)
# Read API key