File size: 3,689 Bytes
98051f8
 
 
3b05d51
98051f8
3b05d51
 
c202241
b17a5c8
f13229f
6d03e59
 
6e18e46
8aab1a5
d7b4e1d
 
3b05d51
 
 
46db6ca
c554635
 
c85ac8f
df3243b
4ae2179
c554635
46db6ca
 
 
06feee8
46db6ca
 
3b05d51
6d03e59
 
 
06feee8
6d03e59
 
361869e
c78cb53
 
06feee8
c78cb53
 
2a808d7
 
f13229f
2a808d7
32b059e
2a808d7
 
 
 
 
 
 
 
b17a5c8
4ae2179
c554635
 
 
 
3b05d51
c554635
06feee8
3b05d51
c554635
 
 
2a808d7
c554635
df3243b
 
b17a5c8
3b05d51
 
b17a5c8
 
4a66e10
06feee8
4a66e10
 
32b059e
 
 
 
 
 
 
 
 
 
 
83b349f
 
 
 
8aab1a5
 
c6896b8
2a808d7
3b05d51
c554635
c78cb53
df3243b
8aab1a5
 
780fd53
347b211
566c2fc
c554635
8aab1a5
 
6e18e46
 
8aab1a5
 
98051f8
8aab1a5
98051f8
8aab1a5
 
a95d8a5
 
06feee8
a95d8a5
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import type { RequestHandler } from "./$types";
import { collections } from "$lib/server/database";
import { ObjectId } from "mongodb";
import { error, redirect } from "@sveltejs/kit";
import { base } from "$app/paths";
import { z } from "zod";
import type { Message } from "$lib/types/Message";
import { models, validateModel } from "$lib/server/models";
import { defaultEmbeddingModel } from "$lib/server/embeddingModels";
import { v4 } from "uuid";
import { authCondition } from "$lib/server/auth";
import { usageLimits } from "$lib/server/usageLimits";
import { MetricsServer } from "$lib/server/metrics";

export const POST: RequestHandler = async ({ locals, request }) => {
	const body = await request.text();

	let title = "";

	const parsedBody = z
		.object({
			fromShare: z.string().optional(),
			model: validateModel(models),
			assistantId: z.string().optional(),
			preprompt: z.string().optional(),
		})
		.safeParse(JSON.parse(body));

	if (!parsedBody.success) {
		error(400, "Invalid request");
	}
	const values = parsedBody.data;

	const convCount = await collections.conversations.countDocuments(authCondition(locals));

	if (usageLimits?.conversations && convCount > usageLimits?.conversations) {
		error(429, "You have reached the maximum number of conversations. Delete some to continue.");
	}

	const model = models.find((m) => (m.id || m.name) === values.model);

	if (!model) {
		error(400, "Invalid model");
	}

	let messages: Message[] = [
		{
			id: v4(),
			from: "system",
			content: values.preprompt ?? "",
			createdAt: new Date(),
			updatedAt: new Date(),
			children: [],
			ancestors: [],
		},
	];

	let rootMessageId: Message["id"] = messages[0].id;
	let embeddingModel: string;

	if (values.fromShare) {
		const conversation = await collections.sharedConversations.findOne({
			_id: values.fromShare,
		});

		if (!conversation) {
			error(404, "Conversation not found");
		}

		title = conversation.title;
		messages = conversation.messages;
		rootMessageId = conversation.rootMessageId ?? rootMessageId;
		values.model = conversation.model;
		values.preprompt = conversation.preprompt;
		values.assistantId = conversation.assistantId?.toString();
		embeddingModel = conversation.embeddingModel;
	}

	embeddingModel ??= model.embeddingModel ?? defaultEmbeddingModel.name;

	if (model.unlisted) {
		error(400, "Can't start a conversation with an unlisted model");
	}

	// get preprompt from assistant if it exists
	const assistant = await collections.assistants.findOne({
		_id: new ObjectId(values.assistantId),
	});

	if (assistant) {
		values.preprompt = assistant.preprompt;
	} else {
		values.preprompt ??= model?.preprompt ?? "";
	}

	if (messages && messages.length > 0 && messages[0].from === "system") {
		messages[0].content = values.preprompt;
	}

	const res = await collections.conversations.insertOne({
		_id: new ObjectId(),
		title: title || "New Chat",
		rootMessageId,
		messages,
		model: values.model,
		preprompt: values.preprompt,
		assistantId: values.assistantId ? new ObjectId(values.assistantId) : undefined,
		createdAt: new Date(),
		updatedAt: new Date(),
		userAgent: request.headers.get("User-Agent") ?? undefined,
		embeddingModel,
		...(locals.user ? { userId: locals.user._id } : { sessionId: locals.sessionId }),
		...(values.fromShare ? { meta: { fromShareId: values.fromShare } } : {}),
	});

	MetricsServer.getMetrics().model.conversationsTotal.inc({ model: values.model });

	return new Response(
		JSON.stringify({
			conversationId: res.insertedId.toString(),
		}),
		{ headers: { "Content-Type": "application/json" } }
	);
};

export const GET: RequestHandler = async () => {
	redirect(302, `${base}/`);
};