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:
@@ -4154,7 +4154,9 @@ initializeDatabase().then(async () => {
|
||||
await dbRun('INSERT INTO chat_messages (user_id, thread_id, role, content) VALUES (?, ?, ?, ?)',
|
||||
[uid(), threadId, 'user', userText]);
|
||||
await dbRun('UPDATE chat_threads SET updated_at = CURRENT_TIMESTAMP WHERE id = ? AND user_id = ?', [threadId, uid()]);
|
||||
// Auto-title the thread from the first user message, if untitled.
|
||||
// Vorläufiger Titel aus der ersten Nachricht, damit in der Seitenleiste
|
||||
// sofort etwas steht. Sobald die Antwort durch ist, formuliert das Modell
|
||||
// daraus einen richtigen Titel (siehe unten).
|
||||
if (!thread.titel) {
|
||||
const first = await dbGet('SELECT content FROM chat_messages WHERE thread_id = ? AND user_id = ? ORDER BY id ASC LIMIT 1', [threadId, uid()]);
|
||||
if (first) {
|
||||
@@ -4232,6 +4234,33 @@ initializeDatabase().then(async () => {
|
||||
send({ type: 'done', messageId: lastID, content: saved, titel: threadRow && threadRow.titel });
|
||||
} catch (error) {
|
||||
send({ type: 'error', message: 'Antwort konnte nicht gespeichert werden.' });
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
// Titel vom Modell formulieren lassen — erst NACH dem 'done', damit die
|
||||
// Antwort nicht auf den Zusatzaufruf warten muss; der Titel kommt als
|
||||
// eigenes Event nach und die Seitenleiste zieht nach.
|
||||
//
|
||||
// Nur beim ersten Schlagabtausch (history = genau die eine Nutzernachricht)
|
||||
// und nur, wenn der Thread vorher keinen Titel hatte — sonst würde ein
|
||||
// selbst vergebener Name wieder überschrieben.
|
||||
const ersterSchlagabtausch = history.length === 1;
|
||||
if (!aborted && !thread.titel && ersterSchlagabtausch && assistantText) {
|
||||
try {
|
||||
const titel = await chat.generateTitle({
|
||||
userText, assistantText, signal: controller.signal,
|
||||
});
|
||||
if (titel && !aborted) {
|
||||
await dbRun(
|
||||
'UPDATE chat_threads SET titel = ? WHERE id = ? AND user_id = ?',
|
||||
[sanitizeInput(titel).slice(0, 120), threadId, uid()]
|
||||
);
|
||||
send({ type: 'titel', titel });
|
||||
}
|
||||
} catch (e) {
|
||||
// Der Fallback-Titel aus der ersten Nachricht steht bereits — nichts tun.
|
||||
}
|
||||
}
|
||||
res.end();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user