feat: add dynamic browser tab titles and improve smart title generation
- Add <svelte:head> to set browser tab title on both new chat and conversation pages - Update tab title dynamically when smart title is generated - Add debug logging to trace title generation flow - Make title generation more robust: - Fall back to user message if assistant content is only thinking - Strip thinking blocks from title generation response - Remove common prefixes like "Title:" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -95,6 +95,9 @@
|
||||
// Add to conversations list
|
||||
conversationsState.add(conversation);
|
||||
|
||||
// Update browser tab title
|
||||
currentTitle = title;
|
||||
|
||||
// Set up chat state for the new conversation
|
||||
chatState.conversationId = conversationId;
|
||||
|
||||
@@ -416,10 +419,14 @@
|
||||
userMessage: string,
|
||||
assistantMessage: string
|
||||
): Promise<void> {
|
||||
console.log('[NewChat] generateSmartTitle called:', { conversationId, userMessage: userMessage.substring(0, 50) });
|
||||
try {
|
||||
// Use a small, fast model for title generation if available, otherwise use selected
|
||||
const model = modelsState.selectedId;
|
||||
if (!model) return;
|
||||
if (!model) {
|
||||
console.log('[NewChat] No model selected, skipping title generation');
|
||||
return;
|
||||
}
|
||||
|
||||
// Strip thinking blocks from assistant message for cleaner title generation
|
||||
const cleanedAssistant = assistantMessage
|
||||
@@ -427,28 +434,44 @@
|
||||
.replace(/<thinking>[\s\S]*?<\/thinking>/g, '')
|
||||
.trim();
|
||||
|
||||
console.log('[NewChat] cleanedAssistant length:', cleanedAssistant.length);
|
||||
|
||||
// Build prompt - use assistant content if available, otherwise just user message
|
||||
const promptContent = cleanedAssistant.length > 0
|
||||
? `User: ${userMessage.substring(0, 200)}\n\nAssistant: ${cleanedAssistant.substring(0, 300)}`
|
||||
: `User message: ${userMessage.substring(0, 400)}`;
|
||||
|
||||
console.log('[NewChat] Generating title with model:', model);
|
||||
|
||||
const response = await ollamaClient.chat({
|
||||
model,
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: 'Generate a very short, concise title (3-6 words max) for this conversation. Output ONLY the title, no quotes, no explanation.'
|
||||
content: 'Generate a very short, concise title (3-6 words max) for this conversation. Output ONLY the title, no quotes, no explanation, no thinking.'
|
||||
},
|
||||
{
|
||||
role: 'user',
|
||||
content: `User: ${userMessage.substring(0, 200)}\n\nAssistant: ${cleanedAssistant.substring(0, 300)}`
|
||||
content: promptContent
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
console.log('[NewChat] Title generation response:', response.message.content);
|
||||
|
||||
// Strip any thinking blocks from the title response and clean it up
|
||||
const newTitle = response.message.content
|
||||
.replace(/<think>[\s\S]*?<\/think>/g, '')
|
||||
.replace(/<thinking>[\s\S]*?<\/thinking>/g, '')
|
||||
.trim()
|
||||
.replace(/^["']|["']$/g, '') // Remove quotes
|
||||
.replace(/^Title:\s*/i, '') // Remove "Title:" prefix if present
|
||||
.substring(0, 50);
|
||||
|
||||
if (newTitle && newTitle.length > 0) {
|
||||
await updateConversation(conversationId, { title: newTitle });
|
||||
conversationsState.update(conversationId, { title: newTitle });
|
||||
currentTitle = newTitle;
|
||||
console.log('[NewChat] Updated title to:', newTitle);
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -456,8 +479,15 @@
|
||||
// Silently fail - keep the original title
|
||||
}
|
||||
}
|
||||
|
||||
// Track current chat title for browser tab
|
||||
let currentTitle = $state<string | null>(null);
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{currentTitle ? `${currentTitle} - Ollama WebUI` : 'Ollama WebUI'}</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="flex h-full flex-col">
|
||||
<ChatWindow mode="new" onFirstMessage={handleFirstMessage} bind:thinkingEnabled />
|
||||
</div>
|
||||
|
||||
@@ -99,6 +99,10 @@
|
||||
);
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{conversation?.title ?? 'Chat'} - Ollama WebUI</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="flex h-full flex-col">
|
||||
{#if isLoading}
|
||||
<!-- Loading state -->
|
||||
|
||||
Reference in New Issue
Block a user