Chat: Klickbare Links zu Beiträgen ermöglicht
- Backend: Markdown-Links [text](/beitrag/ID) → HTML <a> im Reply - Backend: [text](https://...) → klickbare externe Links - Backend: \n → <br> für korrekte Darstellung mit innerHTML - Frontend: textContent → innerHTML (Links werden klickbar) - Ausverkauft-Meldungen: Beitrags-ID im Context für Verlinkung - System-Prompt: Klarere Link-Anweisungen für LLM
This commit is contained in:
@@ -3505,7 +3505,7 @@ def public_frontend():
|
|||||||
|
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.className = 'chat-msg ' + role;
|
div.className = 'chat-msg ' + role;
|
||||||
div.textContent = text;
|
div.innerHTML = text;
|
||||||
wrapper.appendChild(div);
|
wrapper.appendChild(div);
|
||||||
|
|
||||||
if (role === 'assistant') {
|
if (role === 'assistant') {
|
||||||
@@ -4104,7 +4104,7 @@ def api_chat():
|
|||||||
try:
|
try:
|
||||||
for t in meaningful_terms:
|
for t in meaningful_terms:
|
||||||
rows = db.execute(
|
rows = db.execute(
|
||||||
"SELECT spiel_titel, content, halle, published_at FROM submissions "
|
"SELECT id, spiel_titel, content, halle, published_at FROM submissions "
|
||||||
"WHERE status='published' AND deleted_at IS NULL "
|
"WHERE status='published' AND deleted_at IS NULL "
|
||||||
"AND category='ausverkauft' AND spiel_titel IS NOT NULL "
|
"AND category='ausverkauft' AND spiel_titel IS NOT NULL "
|
||||||
"AND LOWER(spiel_titel) LIKE ? LIMIT 5",
|
"AND LOWER(spiel_titel) LIKE ? LIMIT 5",
|
||||||
@@ -4122,7 +4122,7 @@ def api_chat():
|
|||||||
halle = r['halle'] or ''
|
halle = r['halle'] or ''
|
||||||
snippet = (r['content'] or '').strip()[:120]
|
snippet = (r['content'] or '').strip()[:120]
|
||||||
context_parts.append(
|
context_parts.append(
|
||||||
f"[Ausverkauft-Meldung] {title}"
|
f"[Beitrag #{r['id']}] 🔴 AUSVERKAUFT: {title}"
|
||||||
+ (f" | {halle}" if halle else '')
|
+ (f" | {halle}" if halle else '')
|
||||||
+ (f" | {snippet}" if snippet else '')
|
+ (f" | {snippet}" if snippet else '')
|
||||||
)
|
)
|
||||||
@@ -4142,12 +4142,10 @@ def api_chat():
|
|||||||
"- [Aussteller]-Einträge enthalten Verlage/Shops mit Halle, Stand und Land.\n"
|
"- [Aussteller]-Einträge enthalten Verlage/Shops mit Halle, Stand und Land.\n"
|
||||||
"- [Neuheit]-Einträge enthalten Brettspiel-Neuheiten mit Verlag, Halle, Stand und Kategorien.\n"
|
"- [Neuheit]-Einträge enthalten Brettspiel-Neuheiten mit Verlag, Halle, Stand und Kategorien.\n"
|
||||||
"- [Neuheit] mit 'AUSVERKAUFT' = am Stand vergriffen — erwähne das aktiv.\n"
|
"- [Neuheit] mit 'AUSVERKAUFT' = am Stand vergriffen — erwähne das aktiv.\n"
|
||||||
"- [Ausverkauft-Meldung]-Einträge = Community-Berichte über vergriffene Spiele.\n"
|
"- [Beitrag #ID]-Einträge = Community-Beiträge und Ausverkauft-Meldungen.\n"
|
||||||
"- Bei Fragen wie 'ist X noch da?' prüfe Ausverkauft-Status und warne.\n"
|
"- Verlinke Community-Beiträge IMMER so: [Kurzbeschreibung](/beitrag/ID)\n"
|
||||||
"- Wenn du einen Beitrag erwähnst, verlinke ihn IMMER mit der Beitrags-ID aus dem Kontext.\n"
|
" Beispiel: 'Lies [diesen Erfahrungsbericht](/beitrag/53)!'\n"
|
||||||
" Format: [Kurzbeschreibung](/beitrag/ID)\n"
|
" Nimm die ID aus dem [Beitrag #ID]-Tag im Kontext.\n\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 + SPIEL Essen Aussteller):\n{context[:10000]}"
|
f"KONTEXT (veröffentlichte Community-Beiträge + SPIEL Essen Aussteller):\n{context[:10000]}"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -4183,6 +4181,20 @@ def api_chat():
|
|||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
return jsonify({'reply': 'Der BSN Assistent antwortet gerade nicht. Bitte versuch es später nochmal.'})
|
return jsonify({'reply': 'Der BSN Assistent antwortet gerade nicht. Bitte versuch es später nochmal.'})
|
||||||
reply = r.json()["choices"][0]["message"]["content"].strip()
|
reply = r.json()["choices"][0]["message"]["content"].strip()
|
||||||
|
# Markdown-Links [text](url) → klickbare HTML-Links
|
||||||
|
reply = re.sub(
|
||||||
|
r'\[([^\]]+)\]\((https?://[^)]+)\)',
|
||||||
|
r'<a href="\2" target="_blank" rel="noopener" style="color:#20228a;text-decoration:underline;">\1</a>',
|
||||||
|
reply
|
||||||
|
)
|
||||||
|
# Relative Links /beitrag/ID
|
||||||
|
reply = re.sub(
|
||||||
|
r'\[([^\]]+)\]\((/beitrag/\d+)\)',
|
||||||
|
r'<a href="\2" style="color:#20228a;text-decoration:underline;">\1</a>',
|
||||||
|
reply
|
||||||
|
)
|
||||||
|
# Zeilenumbrüche in <br> für innerHTML-Darstellung
|
||||||
|
reply = reply.replace('\n', '<br>')
|
||||||
except Exception:
|
except Exception:
|
||||||
return jsonify({'reply': 'Der BSN Assistent antwortet gerade nicht. Bitte versuch es später nochmal.'})
|
return jsonify({'reply': 'Der BSN Assistent antwortet gerade nicht. Bitte versuch es später nochmal.'})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user