|
|
import { authCondition } from "$lib/server/auth.js"; |
|
|
import { requiresUser } from "$lib/server/auth.js"; |
|
|
import { asssistantSchema } from "./utils.js"; |
|
|
import { uploadAssistantAvatar } from "./utils.js"; |
|
|
import { collections } from "$lib/server/database.js"; |
|
|
import { ObjectId } from "mongodb"; |
|
|
import sharp from "sharp"; |
|
|
import { generateSearchTokens } from "$lib/utils/searchTokens"; |
|
|
import { usageLimits } from "$lib/server/usageLimits.js"; |
|
|
import { ReviewStatus } from "$lib/types/Review.js"; |
|
|
|
|
|
export async function POST({ request, locals }) { |
|
|
const formData = await request.formData(); |
|
|
const parse = await asssistantSchema.safeParseAsync(Object.fromEntries(formData)); |
|
|
|
|
|
if (!parse.success) { |
|
|
|
|
|
const errors = parse.error.errors.map((error) => { |
|
|
return { |
|
|
field: error.path[0], |
|
|
message: error.message, |
|
|
}; |
|
|
}); |
|
|
|
|
|
return new Response(JSON.stringify({ error: true, errors }), { status: 400 }); |
|
|
} |
|
|
|
|
|
|
|
|
if (!locals.user && requiresUser) { |
|
|
const errors = [{ field: "preprompt", message: "Must be logged in. Unauthorized" }]; |
|
|
return new Response(JSON.stringify({ error: true, errors }), { status: 400 }); |
|
|
} |
|
|
|
|
|
const createdById = locals.user?._id ?? locals.sessionId; |
|
|
|
|
|
const assistantsCount = await collections.assistants.countDocuments({ createdById }); |
|
|
|
|
|
if (usageLimits?.assistants && assistantsCount > usageLimits.assistants) { |
|
|
const errors = [ |
|
|
{ |
|
|
field: "preprompt", |
|
|
message: "You have reached the maximum number of assistants. Delete some to continue.", |
|
|
}, |
|
|
]; |
|
|
return new Response(JSON.stringify({ error: true, errors }), { status: 400 }); |
|
|
} |
|
|
|
|
|
const newAssistantId = new ObjectId(); |
|
|
|
|
|
const exampleInputs: string[] = [ |
|
|
parse?.data?.exampleInput1 ?? "", |
|
|
parse?.data?.exampleInput2 ?? "", |
|
|
parse?.data?.exampleInput3 ?? "", |
|
|
parse?.data?.exampleInput4 ?? "", |
|
|
].filter((input) => !!input); |
|
|
|
|
|
let hash; |
|
|
if (parse.data.avatar && parse.data.avatar instanceof File && parse.data.avatar.size > 0) { |
|
|
let image; |
|
|
try { |
|
|
image = await sharp(await parse.data.avatar.arrayBuffer()) |
|
|
.resize(512, 512, { fit: "inside" }) |
|
|
.jpeg({ quality: 80 }) |
|
|
.toBuffer(); |
|
|
} catch (e) { |
|
|
const errors = [{ field: "avatar", message: (e as Error).message }]; |
|
|
return new Response(JSON.stringify({ error: true, errors }), { status: 400 }); |
|
|
} |
|
|
|
|
|
hash = await uploadAssistantAvatar(new File([image], "avatar.jpg"), newAssistantId); |
|
|
} |
|
|
|
|
|
const { insertedId } = await collections.assistants.insertOne({ |
|
|
_id: newAssistantId, |
|
|
createdById, |
|
|
createdByName: locals.user?.username ?? locals.user?.name, |
|
|
...parse.data, |
|
|
tools: parse.data.tools, |
|
|
exampleInputs, |
|
|
avatar: hash, |
|
|
createdAt: new Date(), |
|
|
updatedAt: new Date(), |
|
|
userCount: 1, |
|
|
review: ReviewStatus.PRIVATE, |
|
|
rag: { |
|
|
allowedLinks: parse.data.ragLinkList, |
|
|
allowedDomains: parse.data.ragDomainList, |
|
|
allowAllDomains: parse.data.ragAllowAll, |
|
|
}, |
|
|
dynamicPrompt: parse.data.dynamicPrompt, |
|
|
searchTokens: generateSearchTokens(parse.data.name), |
|
|
last24HoursCount: 0, |
|
|
generateSettings: { |
|
|
temperature: parse.data.temperature, |
|
|
top_p: parse.data.top_p, |
|
|
repetition_penalty: parse.data.repetition_penalty, |
|
|
top_k: parse.data.top_k, |
|
|
}, |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
await collections.settings.updateOne(authCondition(locals), { |
|
|
$addToSet: { assistants: insertedId }, |
|
|
}); |
|
|
|
|
|
return new Response(JSON.stringify({ success: true, assistantId: insertedId }), { status: 200 }); |
|
|
} |
|
|
|