-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathroute.ts
74 lines (63 loc) · 2.31 KB
/
route.ts
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
import { NextRequest, NextResponse } from "next/server";
import { Prisma, embeddings } from "@prisma/client";
import { prisma } from "@/lib/prisma";
import { PrismaVectorStore } from "langchain/vectorstores/prisma";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import { getServerSessionUserId } from "@/lib/auth";
const vectorStore = PrismaVectorStore.withModel<embeddings>(prisma).create(new OpenAIEmbeddings(), {
prisma: Prisma,
tableName: 'embeddings',
vectorColumnName: 'embedding',
columns: {
embedding_id: PrismaVectorStore.IdColumn,
content: PrismaVectorStore.ContentColumn,
apartment_id: true
},
})
export async function PUT(req: NextRequest, { params }: { params: { fileId: string } }) {
const fileId = Number.parseInt(params.fileId)
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 300,
chunkOverlap: 40,
})
const userId = await getServerSessionUserId()
const file = await prisma.files.findFirst({
include: {
embeddings: true
},
where: {
file_id: fileId,
folders: {
user_id: userId
}
}
})
if (!file) return new NextResponse(null, { status: 404 })
const newContents = await splitter.splitText(file.content)
const existingContents = file.embeddings.map(e => e.content)
// insert only embeddings with unique content in case when user changes only part of file content
const contentsToInsert = newContents.filter(nc => !existingContents.includes(nc))
const newEmbeddings = await prisma.$transaction(
contentsToInsert.map(cont => prisma.embeddings.create({
data: {
content: cont,
file_id: file.file_id
}
}))
)
// new file embeddings is all embeddings that are about new content
const fileEmbeddings = file.embeddings.filter(em => newContents.includes(em.content))
.concat(newEmbeddings)
// populate new embeddings with vectors and then (if success) delete embeddings that are not about new content
vectorStore.addModels(newEmbeddings)
.then(() => prisma.embeddings.deleteMany({
where: {
file_id: file.file_id,
embedding_id: {
notIn: fileEmbeddings.map(fe => fe.embedding_id)
}
}
}))
return new NextResponse(null, { status: 204 })
}