KI-Chat: Thread-Titel vom Modell formulieren lassen

Der Titel in der Seitenleiste waren bisher die ersten 60 Zeichen der
ersten Nachricht - abgeschnitten mitten im Wort ("Ich habe mich bei der
Hetzner Online GmbH bewor..."). Jetzt formuliert das Modell daraus einen
kurzen Titel, wie man es aus ChatGPT kennt.

- Der Aufruf laeuft NACH dem done-Event: die Antwort wartet nicht auf die
  Titelgenerierung (1-3 s), der Titel kommt als eigenes Event nach und die
  Seitenleiste zieht live nach.
- Der abgeschnittene Titel bleibt als Platzhalter, solange die Antwort
  streamt - die Seitenleiste ist also nie leer, und faellt die
  Titelgenerierung aus, bleibt es schlicht dabei.
- Nur beim ersten Schlagabtausch und nur, wenn der Thread noch keinen
  Titel hatte: ein selbst vergebener Name wird nicht ueberschrieben.
- Eigener Mini-Systemprompt statt des Chat-Prompts, der will beraten,
  nicht betiteln. Anfuehrungszeichen/"Titel:"-Praefixe werden abgeraeumt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 12:19:27 +02:00
co-authored by Claude Opus 4.8
parent 4b3e66b4bd
commit 67b8e5735f
3 changed files with 84 additions and 7 deletions
+14 -5
View File
@@ -213,6 +213,15 @@
return wrap;
}
// Titel des aktiven Threads in der Seitenleiste setzen (kein innerHTML: der
// Titel kommt aus einer Modellantwort).
function setThreadTitle(titel) {
if (!titel || !activeId) return;
const li = threadList && threadList.querySelector('li[data-thread-li="' + activeId + '"]');
const titleEl = li && li.querySelector('.threadLink .font-medium');
if (titleEl && titel !== titleEl.textContent) titleEl.textContent = titel;
}
function prependThread(id, titel) {
if (!threadList) return;
const empty = threadList.querySelector('li.text-center');
@@ -350,12 +359,12 @@
addMessage('assistant', ev.content || '(keine Antwort)');
}
// Live-update the auto-generated thread title in the sidebar.
if (ev.titel && activeId) {
const li = threadList && threadList.querySelector('li[data-thread-li="' + activeId + '"]');
const titleEl = li && li.querySelector('.threadLink .font-medium');
if (titleEl && ev.titel && ev.titel !== titleEl.textContent) titleEl.textContent = ev.titel;
}
setThreadTitle(ev.titel);
scrollBottom();
} else if (ev.type === 'titel') {
// Kommt nach 'done' nach: der vom Modell formulierte Titel löst den
// vorläufigen (abgeschnittene erste Nachricht) in der Seitenleiste ab.
setThreadTitle(ev.titel);
} else if (ev.type === 'error') {
if (typing) typing.remove();
if (!assistantBubble) addMessage('assistant', 'Fehler: ' + ev.message);