File size: 3,437 Bytes
5da61b4
 
 
0bfcf81
5da61b4
0bfcf81
 
b7b2c8c
3a01622
d8e839e
537b6f5
 
1b66f8d
2e28042
 
0bfcf81
 
 
06e879d
 
 
cf7ac8d
992a8de
af58e08
06e879d
 
0bfcf81
537b6f5
 
 
 
 
 
 
 
 
e6addfc
 
d8e839e
e6addfc
 
 
 
 
 
 
 
 
 
3a01622
af58e08
06e879d
 
 
 
0bfcf81
06e879d
 
0bfcf81
06e879d
 
 
e6addfc
06e879d
992a8de
 
3a01622
0bfcf81
 
af58e08
41f29a4
 
 
 
 
3a01622
 
41f29a4
 
 
 
e6e851b
992a8de
 
 
 
 
 
 
 
 
 
af58e08
1b66f8d
 
f249cfc
e6addfc
0bfcf81
06e879d
e6e851b
992a8de
1b66f8d
 
d5559df
64d3841
06e879d
1b66f8d
 
 
 
5da61b4
1b66f8d
5da61b4
1b66f8d
 
7b62aec
 
767afa7
7b62aec
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
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";

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

	let title = "";

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

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

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

	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) {
			throw 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;
	}

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

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

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

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

	// Use the model preprompt if there is no conversation/preprompt in the request body
	const preprompt = await (async () => {
		if (values.assistantId) {
			const assistant = await collections.assistants.findOne({
				_id: new ObjectId(values.assistantId),
			});
			return assistant?.preprompt;
		} else {
			return values?.preprompt ?? model?.preprompt;
		}
	})();

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

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

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