feat(chat): add auto-title generation after first exchange (M8.5)

After the first AI response, sends a background request to generate
a 3-5 word title using Claude Haiku. Silently replaces the default
title derived from the first user message.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-03 23:10:46 +00:00
co-authored by Claude Opus 4.6
parent 5d3114b142
commit 68e296278c
+48
View File
@@ -281,6 +281,51 @@ function formatWebSearchContext(results: { title: string; url: string; content?:
let currentAbort: AbortController | null = null
/** Background title generation after first exchange */
async function generateAutoTitle(conversationId: string) {
const chatStore = useChatStore()
const conv = chatStore.conversations.get(conversationId)
if (!conv) return
// Only auto-title after first exchange (1 user + 1 assistant message)
if (conv.messages.length !== 2) return
const userMsg = conv.messages[0]
if (userMsg.role !== 'user') return
// Skip if title was manually set (not auto-generated from first message)
const autoTitle = userMsg.content.slice(0, 60) + (userMsg.content.length > 60 ? '...' : '')
if (conv.title !== autoTitle) return
try {
const headers: Record<string, string> = { 'Content-Type': 'application/json' }
const vaultKey = await getApiKey('claude')
if (vaultKey) headers['x-api-key'] = vaultKey
const res = await fetch(CLAUDE_PATH, {
method: 'POST',
headers,
body: JSON.stringify({
model: 'claude-haiku-4.5',
system: 'You generate very short conversation titles. Respond with ONLY a 3-5 word title, no quotes, no punctuation at the end.',
messages: [{ role: 'user', content: `Title this conversation: "${userMsg.content.slice(0, 200)}"` }],
max_tokens: 20,
stream: false,
}),
})
if (!res.ok) return
const data = await res.json()
const title = data?.content?.[0]?.text?.trim()
if (title && title.length > 0 && title.length < 60) {
conv.title = title
conv.updatedAt = Date.now()
}
} catch {
// Silent fail — title stays as default
}
}
export function useAI() {
const chatStore = useChatStore()
@@ -353,6 +398,9 @@ export function useAI() {
currentAbort = null
chatStore.isStreaming = false
}
// Auto-title: generate a short title after first exchange
generateAutoTitle(cid)
}
/**