File size: 3,473 Bytes
5da61b4
 
 
0bfcf81
5da61b4
0bfcf81
 
b7b2c8c
3a01622
d8e839e
537b6f5
 
1b66f8d
2e28042
 
0bfcf81
 
 
403d4bd
06e879d
 
cf7ac8d
992a8de
af58e08
06e879d
403d4bd
 
 
 
 
 
0bfcf81
537b6f5
 
 
 
 
 
 
 
 
7849c30
bcfa394
 
 
 
 
403d4bd
bcfa394
 
 
 
 
 
 
 
 
 
e6addfc
 
d8e839e
e6addfc
bcfa394
e6addfc
 
 
 
 
 
 
 
3a01622
af58e08
06e879d
 
 
 
0bfcf81
06e879d
 
0bfcf81
06e879d
 
 
e6addfc
06e879d
992a8de
 
3a01622
0bfcf81
 
3a01622
 
41f29a4
 
 
 
1b66f8d
 
f249cfc
e6addfc
0bfcf81
06e879d
bcfa394
992a8de
1b66f8d
 
d196c64
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
121
122
123
124
125
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 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) {
		throw error(400, "Invalid request");
	}
	const values = parsedBody.data;

	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."
		);
	}

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

	if (!model) {
		throw error(400, "Invalid 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 ?? "";
	}

	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;
	}

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

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

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

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

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