chat_ui / src /lib /server /api /routes /groups /user.ts
maksym-work's picture
add chat-ui
e28a7d6
import { Elysia } from "elysia";
import { authPlugin } from "$api/authPlugin";
import { defaultModel } from "$lib/server/models";
import { collections } from "$lib/server/database";
import { authCondition } from "$lib/server/auth";
import { models, validateModel } from "$lib/server/models";
import { DEFAULT_SETTINGS, type SettingsEditable } from "$lib/types/Settings";
import { toolFromConfigs } from "$lib/server/tools";
import { ObjectId } from "mongodb";
import { z } from "zod";
export const userGroup = new Elysia()
.use(authPlugin)
.get("/login", () => {
// todo: login
throw new Error("Not implemented");
})
.get("/login/callback", () => {
// todo: login callback
throw new Error("Not implemented");
})
.post("/logout", () => {
// todo: logout
throw new Error("Not implemented");
})
.group("/user", (app) => {
return app
.get("/", ({ locals }) => {
return locals.user
? {
id: locals.user._id.toString(),
username: locals.user.username,
avatarUrl: locals.user.avatarUrl,
email: locals.user.email,
logoutDisabled: locals.user.logoutDisabled,
isAdmin: locals.user.isAdmin ?? false,
isEarlyAccess: locals.user.isEarlyAccess ?? false,
}
: null;
})
.get("/settings", async ({ locals }) => {
const settings = await collections.settings.findOne(authCondition(locals));
if (
settings &&
!validateModel(models).safeParse(settings?.activeModel).success &&
!settings.assistants?.map((el) => el.toString())?.includes(settings?.activeModel)
) {
settings.activeModel = defaultModel.id;
await collections.settings.updateOne(authCondition(locals), {
$set: { activeModel: defaultModel.id },
});
}
// if the model is unlisted, set the active model to the default model
if (
settings?.activeModel &&
models.find((m) => m.id === settings?.activeModel)?.unlisted === true
) {
settings.activeModel = defaultModel.id;
await collections.settings.updateOne(authCondition(locals), {
$set: { activeModel: defaultModel.id },
});
}
// todo: get user settings
return {
ethicsModalAccepted: !!settings?.ethicsModalAcceptedAt,
ethicsModalAcceptedAt: settings?.ethicsModalAcceptedAt ?? null,
activeModel: settings?.activeModel ?? DEFAULT_SETTINGS.activeModel,
hideEmojiOnSidebar: settings?.hideEmojiOnSidebar ?? DEFAULT_SETTINGS.hideEmojiOnSidebar,
disableStream: settings?.disableStream ?? DEFAULT_SETTINGS.disableStream,
directPaste: settings?.directPaste ?? DEFAULT_SETTINGS.directPaste,
shareConversationsWithModelAuthors:
settings?.shareConversationsWithModelAuthors ??
DEFAULT_SETTINGS.shareConversationsWithModelAuthors,
customPrompts: settings?.customPrompts ?? {},
assistants: settings?.assistants?.map((assistantId) => assistantId.toString()) ?? [],
tools:
settings?.tools ??
toolFromConfigs
.filter((el) => !el.isHidden && el.isOnByDefault)
.map((el) => el._id.toString()),
};
})
.post("/settings", async ({ locals, request }) => {
const body = await request.json();
const { ethicsModalAccepted, ...settings } = z
.object({
shareConversationsWithModelAuthors: z
.boolean()
.default(DEFAULT_SETTINGS.shareConversationsWithModelAuthors),
hideEmojiOnSidebar: z.boolean().default(DEFAULT_SETTINGS.hideEmojiOnSidebar),
ethicsModalAccepted: z.boolean().optional(),
activeModel: z.string().default(DEFAULT_SETTINGS.activeModel),
customPrompts: z.record(z.string()).default({}),
tools: z.array(z.string()).optional(),
disableStream: z.boolean().default(false),
directPaste: z.boolean().default(false),
})
.parse(body) satisfies SettingsEditable;
// make sure all tools exist
// either in db or in config
if (settings.tools) {
const newTools = [
...(await collections.tools
.find({ _id: { $in: settings.tools.map((toolId) => new ObjectId(toolId)) } })
.project({ _id: 1 })
.toArray()
.then((tools) => tools.map((tool) => tool._id.toString()))),
...toolFromConfigs
.filter((el) => (settings?.tools ?? []).includes(el._id.toString()))
.map((el) => el._id.toString()),
];
settings.tools = newTools;
}
await collections.settings.updateOne(
authCondition(locals),
{
$set: {
...settings,
...(ethicsModalAccepted && { ethicsModalAcceptedAt: new Date() }),
updatedAt: new Date(),
},
$setOnInsert: {
createdAt: new Date(),
},
},
{
upsert: true,
}
);
// return ok response
return new Response();
})
.get("/reports", async ({ locals }) => {
if (!locals.user || !locals.sessionId) {
return [];
}
const reports = await collections.reports
.find({
createdBy: locals.user?._id ?? locals.sessionId,
})
.toArray();
return reports;
})
.get("/assistant/active", async ({ locals }) => {
const settings = await collections.settings.findOne(authCondition(locals));
if (!settings) {
return null;
}
if (settings.assistants?.map((el) => el.toString())?.includes(settings?.activeModel)) {
return await collections.assistants.findOne({
_id: new ObjectId(settings.activeModel),
});
}
return null;
})
.get("/assistants", async ({ locals }) => {
const settings = await collections.settings.findOne(authCondition(locals));
if (!settings) {
return [];
}
const userAssistants =
settings?.assistants?.map((assistantId) => assistantId.toString()) ?? [];
const assistants = await collections.assistants
.find({
_id: {
$in: [...userAssistants.map((el) => new ObjectId(el))],
},
})
.toArray();
return assistants.map((el) => ({
...el,
_id: el._id.toString(),
createdById: undefined,
createdByMe:
el.createdById.toString() === (locals.user?._id ?? locals.sessionId).toString(),
}));
});
});