File size: 2,281 Bytes
48059af
43606a3
486ffa7
564e576
 
bf75aa7
7aa951e
564e576
 
 
 
 
 
 
 
 
7bf1507
 
564e576
 
 
 
 
 
ee5c213
564e576
 
 
7bf1507
48059af
7bf1507
2bae046
 
ee1ec85
7bf1507
6655689
bf75aa7
 
7bf1507
 
 
 
 
 
 
 
3b53c7a
 
 
7bf1507
bf75aa7
 
43606a3
7bf1507
 
 
 
43606a3
 
486ffa7
7bf1507
 
43606a3
7aa951e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import { config } from "$lib/server/config";
import { generateFromDefaultEndpoint } from "$lib/server/generateFromDefaultEndpoint";
import { logger } from "$lib/server/logger";
import { MessageUpdateType, type MessageUpdate } from "$lib/types/MessageUpdate";
import type { Conversation } from "$lib/types/Conversation";
import { getReturnFromGenerator } from "$lib/utils/getReturnFromGenerator";

export async function* generateTitleForConversation(
	conv: Conversation
): AsyncGenerator<MessageUpdate, undefined, undefined> {
	try {
		const userMessage = conv.messages.find((m) => m.from === "user");
		// HACK: detect if the conversation is new
		if (conv.title !== "New Chat" || !userMessage) return;

		const prompt = userMessage.content;
		const modelForTitle = config.TASK_MODEL?.trim() ? config.TASK_MODEL : conv.model;
		const title = (await generateTitle(prompt, modelForTitle)) ?? "New Chat";

		yield {
			type: MessageUpdateType.Title,
			title,
		};
	} catch (cause) {
		logger.error(Error("Failed whilte generating title for conversation", { cause }));
	}
}

export async function generateTitle(prompt: string, modelId?: string) {
	if (config.LLM_SUMMARIZATION !== "true") {
		// When summarization is disabled, use the first five words without adding emojis
		return prompt.split(/\s+/g).slice(0, 5).join(" ");
	}

	// Tools removed: no tool-based title path

	return await getReturnFromGenerator(
		generateFromDefaultEndpoint({
			messages: [{ from: "user", content: `Prompt to summarize: "${prompt}"` }],
			preprompt: `You are a titling assistant.
Summarize the user's request into a short title of at most 4 words.
Use the SAME language as the user's message.
Do not answer the question.
Do not include the word prompt into your response.
Do not include quotes, emojis, hashtags or trailing punctuation.
Return ONLY the title text.`,
			generateSettings: {
				max_tokens: 30,
			},
			modelId,
		})
	)
		.then((summary) => {
			const firstFive = prompt.split(/\s+/g).slice(0, 5).join(" ");
			const trimmed = summary.trim();
			// Fallback: if empty, return first five words only (no emoji)
			return trimmed || firstFive;
		})
		.catch((e) => {
			logger.error(e);
			const firstFive = prompt.split(/\s+/g).slice(0, 5).join(" ");
			return firstFive;
		});
}