diff options
| author | yxshv <[email protected]> | 2024-04-14 14:32:12 +0530 |
|---|---|---|
| committer | yxshv <[email protected]> | 2024-04-14 14:32:12 +0530 |
| commit | ac41d347711b7f056a2cf8564d25dc425eb3aa8d (patch) | |
| tree | 4b921f0868d3b3d64ffcccebf2e353c4fc969bd7 | |
| parent | new modals (diff) | |
| parent | 6144 char limit (diff) | |
| download | supermemory-ac41d347711b7f056a2cf8564d25dc425eb3aa8d.tar.xz supermemory-ac41d347711b7f056a2cf8564d25dc425eb3aa8d.zip | |
merge
21 files changed, 182 insertions, 14 deletions
diff --git a/apps/cf-ai-backend/package.json b/apps/cf-ai-backend/package.json index 342fb7ff..30df6ec7 100644 --- a/apps/cf-ai-backend/package.json +++ b/apps/cf-ai-backend/package.json @@ -5,7 +5,8 @@ "scripts": { "deploy": "wrangler deploy", "dev": "wrangler dev", - "start": "wrangler dev" + "start": "wrangler dev", + "unsafe-reset-vector-db": "wrangler vectorize delete supermem-vector && wrangler vectorize create --dimensions=1536 supermem-vector-1 --metric=cosine" }, "devDependencies": { "@cloudflare/workers-types": "^4.20240222.0", diff --git a/apps/cf-ai-backend/src/routes.ts b/apps/cf-ai-backend/src/routes.ts index ff1218e8..b9e1cdb4 100644 --- a/apps/cf-ai-backend/src/routes.ts +++ b/apps/cf-ai-backend/src/routes.ts @@ -5,6 +5,9 @@ import * as apiAsk from './routes/ask'; import * as apiChat from './routes/chat'; import * as apiBatchUploadTweets from './routes/batchUploadTweets'; import * as apiGetPageContent from './routes/getPageContent'; +import * as apiDelete from './routes/delete'; +import * as apiEdit from './routes/edit'; +import * as apiWipeData from './routes/wipedata'; import { OpenAIEmbeddings } from './OpenAIEmbedder'; import { GenerativeModel } from '@google/generative-ai'; import { Request } from '@cloudflare/workers-types'; @@ -30,7 +33,10 @@ routeMap.set('/chat', apiChat); routeMap.set('/batchUploadTweets', apiBatchUploadTweets); routeMap.set('/getPageContent', apiGetPageContent); +routeMap.set('/delete', apiDelete); +routeMap.set('/edit', apiEdit); +routeMap.set('/wipedata', apiWipeData); // Add more route mappings as needed // routeMap.set('/api/otherRoute', { ... }); diff --git a/apps/cf-ai-backend/src/routes/add.ts b/apps/cf-ai-backend/src/routes/add.ts index 940287e3..173c12b9 100644 --- a/apps/cf-ai-backend/src/routes/add.ts +++ b/apps/cf-ai-backend/src/routes/add.ts @@ -17,6 +17,10 @@ export async function POST(request: Request, store: CloudflareVectorizeStore, _: if (!body.pageContent || !body.url) { return new Response(JSON.stringify({ message: 'Invalid Page Content' }), { status: 400 }); } + + // TODO: FIX THIS,BUT TEMPERORILY TRIM page content to 1000 words + body.pageContent = body.pageContent.split(' ').slice(0, 1000).join(' '); + const newPageContent = `Title: ${body.title}\nDescription: ${body.description}\nURL: ${body.url}\nContent: ${body.pageContent}`; const ourID = `${body.url}-${body.user}`; @@ -31,7 +35,7 @@ export async function POST(request: Request, store: CloudflareVectorizeStore, _: { pageContent: newPageContent, metadata: { - title: body.title ?? '', + title: body.title?.slice(0, 50) ?? '', description: body.description ?? '', space: body.space ?? '', url: body.url, diff --git a/apps/cf-ai-backend/src/routes/chat.ts b/apps/cf-ai-backend/src/routes/chat.ts index 93bdd7ab..77ee1fd9 100644 --- a/apps/cf-ai-backend/src/routes/chat.ts +++ b/apps/cf-ai-backend/src/routes/chat.ts @@ -143,7 +143,7 @@ export async function POST(request: Request, _: CloudflareVectorizeStore, embedd const ai = new Ai(env?.AI); // @ts-ignore const output: AiTextGenerationOutput = (await ai.run('@hf/mistralai/mistral-7b-instruct-v0.2', { - prompt, + prompt: prompt.slice(0, 6144), stream: true, })) as ReadableStream; diff --git a/apps/cf-ai-backend/src/routes/delete.ts b/apps/cf-ai-backend/src/routes/delete.ts new file mode 100644 index 00000000..bb28ce9d --- /dev/null +++ b/apps/cf-ai-backend/src/routes/delete.ts @@ -0,0 +1,27 @@ +import { Request } from '@cloudflare/workers-types'; +import { type CloudflareVectorizeStore } from '@langchain/cloudflare'; +import { OpenAIEmbeddings } from '../OpenAIEmbedder'; +import { GenerativeModel } from '@google/generative-ai'; +import { seededRandom } from '../util'; + +export async function DELETE(request: Request, store: CloudflareVectorizeStore, _: OpenAIEmbeddings, m: GenerativeModel, env: Env) { + const { searchParams } = new URL(request.url); + const websiteUrl = searchParams.get('websiteUrl'); + const user = searchParams.get('user'); + + if (!websiteUrl || !user) { + return new Response(JSON.stringify({ message: 'Invalid Request, need websiteUrl and user' }), { status: 400 }); + } + + const ourID = `${websiteUrl}-${user}`; + + const uuid = await env.KV.get(ourID); + + if (!uuid) { + return new Response(JSON.stringify({ message: 'Document not found' }), { status: 404 }); + } + + await store.delete({ ids: [uuid] }); + + return new Response(JSON.stringify({ message: 'Document deleted' }), { status: 200 }); +} diff --git a/apps/cf-ai-backend/src/routes/edit.ts b/apps/cf-ai-backend/src/routes/edit.ts new file mode 100644 index 00000000..e32c93ca --- /dev/null +++ b/apps/cf-ai-backend/src/routes/edit.ts @@ -0,0 +1,61 @@ +import { Request } from '@cloudflare/workers-types'; +import { type CloudflareVectorizeStore } from '@langchain/cloudflare'; +import { OpenAIEmbeddings } from '../OpenAIEmbedder'; +import { GenerativeModel } from '@google/generative-ai'; +import { seededRandom } from '../util'; + +export async function POST(request: Request, store: CloudflareVectorizeStore, _: OpenAIEmbeddings, m: GenerativeModel, env: Env) { + const body = (await request.json()) as { + pageContent: string; + title?: string; + description?: string; + space?: string; + url: string; + user: string; + }; + + if (!body.pageContent || !body.url) { + return new Response(JSON.stringify({ message: 'Invalid Page Content' }), { status: 400 }); + } + + const { searchParams } = new URL(request.url); + const uniqueUrl = searchParams.get('uniqueUrl'); + + const toBeDeleted = `${uniqueUrl}-${body.user}`; + const tbduuid = await env.KV.get(toBeDeleted); + if (tbduuid) { + await store.delete({ ids: [tbduuid] }); + } + + // TODO: FIX THIS,BUT TEMPERORILY TRIM page content to 1000 words + body.pageContent = body.pageContent.split(' ').slice(0, 1000).join(' '); + + const newPageContent = `Title: ${body.title}\nDescription: ${body.description}\nURL: ${body.url}\nContent: ${body.pageContent}`; + + const ourID = `${body.url}-${body.user}`; + + const random = seededRandom(ourID); + const uuid = random().toString(36).substring(2, 15) + random().toString(36).substring(2, 15); + + await env.KV.put(uuid, ourID); + + await store.addDocuments( + [ + { + pageContent: newPageContent, + metadata: { + title: body.title?.slice(0, 50) ?? '', + description: body.description ?? '', + space: body.space ?? '', + url: body.url, + user: body.user, + }, + }, + ], + { + ids: [uuid], + }, + ); + + return new Response(JSON.stringify({ message: 'Document Added' }), { status: 200 }); +} diff --git a/apps/cf-ai-backend/src/routes/queue.ts b/apps/cf-ai-backend/src/routes/queue.ts index 9dcef525..89a00c4b 100644 --- a/apps/cf-ai-backend/src/routes/queue.ts +++ b/apps/cf-ai-backend/src/routes/queue.ts @@ -37,7 +37,7 @@ export const queue = async (batch: MessageBatch, env: Env): Promise<void> => { const collectedDocsUUIDs: { document: { pageContent: string; - metadata: { title: string; description: string; space: string; url: string; user: string }; + metadata: { title: string; description: string; space?: string; url: string; user: string }; id: string; }; }[] = []; @@ -57,7 +57,6 @@ export const queue = async (batch: MessageBatch, env: Env): Promise<void> => { metadata: { title: 'Twitter Bookmark', description: '', - space: 'Bookmarked Tweets', url: message.postUrl, user: limits.user, }, diff --git a/apps/cf-ai-backend/src/routes/wipedata.ts b/apps/cf-ai-backend/src/routes/wipedata.ts new file mode 100644 index 00000000..841330f8 --- /dev/null +++ b/apps/cf-ai-backend/src/routes/wipedata.ts @@ -0,0 +1,19 @@ +import { Request } from '@cloudflare/workers-types'; +import { type CloudflareVectorizeStore } from '@langchain/cloudflare'; +import { OpenAIEmbeddings } from '../OpenAIEmbedder'; +import { GenerativeModel } from '@google/generative-ai'; +import { seededRandom } from '../util'; + +// TODO: Waiting for cloudflare to implement tojson so i can get all IDS for that user and delete them +export async function DELETE(request: Request, store: CloudflareVectorizeStore, _: OpenAIEmbeddings, m: GenerativeModel, env: Env) { + const { searchParams } = new URL(request.url); + const user = searchParams.get('user'); + + console.log(store.toJSONNotImplemented()); + + // for (const match of matches.matches) { + // await store.delete({ ids: [match.id] }); + // } + + return new Response(JSON.stringify({ message: 'Document deleted' }), { status: 200 }); +} diff --git a/apps/cf-ai-backend/wrangler.toml b/apps/cf-ai-backend/wrangler.toml index 832d9e0d..3ef9b045 100644 --- a/apps/cf-ai-backend/wrangler.toml +++ b/apps/cf-ai-backend/wrangler.toml @@ -5,7 +5,7 @@ compatibility_flags = ['nodejs_compat'] [[vectorize]] binding = "VECTORIZE_INDEX" -index_name = "supermem-vector" +index_name = "supermem-vector-1" [ai] binding = "AI" diff --git a/apps/web/db/prepare.sql b/apps/web/db/prepare.sql index dcba4d40..4c8c2af6 100644 --- a/apps/web/db/prepare.sql +++ b/apps/web/db/prepare.sql @@ -13,15 +13,15 @@ CREATE TABLE `account` ( `session_state` text(255), `oauth_token_secret` text, `oauth_token` text, - FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE no action + FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade ); --> statement-breakpoint CREATE TABLE `contentToSpace` ( `contentId` integer NOT NULL, `spaceId` integer NOT NULL, PRIMARY KEY(`contentId`, `spaceId`), - FOREIGN KEY (`contentId`) REFERENCES `storedContent`(`id`) ON UPDATE no action ON DELETE no action, - FOREIGN KEY (`spaceId`) REFERENCES `space`(`id`) ON UPDATE no action ON DELETE no action + FOREIGN KEY (`contentId`) REFERENCES `storedContent`(`id`) ON UPDATE no action ON DELETE cascade, + FOREIGN KEY (`spaceId`) REFERENCES `space`(`id`) ON UPDATE no action ON DELETE cascade ); --> statement-breakpoint CREATE TABLE `session` ( @@ -29,14 +29,14 @@ CREATE TABLE `session` ( `sessionToken` text(255) NOT NULL, `userId` text(255) NOT NULL, `expires` integer NOT NULL, - FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE no action + FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade ); --> statement-breakpoint CREATE TABLE `space` ( `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL, `name` text DEFAULT 'none' NOT NULL, `user` text(255), - FOREIGN KEY (`user`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE no action + FOREIGN KEY (`user`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade ); --> statement-breakpoint CREATE TABLE `storedContent` ( @@ -50,7 +50,7 @@ CREATE TABLE `storedContent` ( `type` text DEFAULT 'page', `image` text(255), `user` text(255), - FOREIGN KEY (`user`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE no action + FOREIGN KEY (`user`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade ); --> statement-breakpoint CREATE TABLE `user` ( diff --git a/apps/web/db/wipe.sql b/apps/web/db/wipe.sql new file mode 100644 index 00000000..456a48ad --- /dev/null +++ b/apps/web/db/wipe.sql @@ -0,0 +1,7 @@ +DELETE FROM `account`; +DELETE FROM `contentToSpace`; +DELETE FROM `session`; +DELETE FROM `space`; +DELETE FROM `storedContent`; +DELETE FROM `user`; +DELETE FROM `verificationToken`;
\ No newline at end of file diff --git a/apps/web/public/android-chrome-192x192.png b/apps/web/public/android-chrome-192x192.png Binary files differnew file mode 100644 index 00000000..5e57b282 --- /dev/null +++ b/apps/web/public/android-chrome-192x192.png diff --git a/apps/web/public/android-chrome-512x512.png b/apps/web/public/android-chrome-512x512.png Binary files differnew file mode 100644 index 00000000..2553425e --- /dev/null +++ b/apps/web/public/android-chrome-512x512.png diff --git a/apps/web/public/apple-touch-icon.png b/apps/web/public/apple-touch-icon.png Binary files differnew file mode 100644 index 00000000..d55c6339 --- /dev/null +++ b/apps/web/public/apple-touch-icon.png diff --git a/apps/web/public/favicon-16x16.png b/apps/web/public/favicon-16x16.png Binary files differnew file mode 100644 index 00000000..67fbac93 --- /dev/null +++ b/apps/web/public/favicon-16x16.png diff --git a/apps/web/public/favicon-32x32.png b/apps/web/public/favicon-32x32.png Binary files differnew file mode 100644 index 00000000..2fc8f0b3 --- /dev/null +++ b/apps/web/public/favicon-32x32.png diff --git a/apps/web/public/favicon.ico b/apps/web/public/favicon.ico Binary files differnew file mode 100644 index 00000000..163c3627 --- /dev/null +++ b/apps/web/public/favicon.ico diff --git a/apps/web/public/og-image.png b/apps/web/public/og-image.png Binary files differnew file mode 100644 index 00000000..1050ff19 --- /dev/null +++ b/apps/web/public/og-image.png diff --git a/apps/web/public/site.webmanifest b/apps/web/public/site.webmanifest new file mode 100644 index 00000000..8d302080 --- /dev/null +++ b/apps/web/public/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "Supermemory - Your second brain", + "short_name": "Save your memories forever, build your own second brain.", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/apps/web/src/app/favicon.ico b/apps/web/src/app/favicon.ico Binary files differdeleted file mode 100644 index 718d6fea..00000000 --- a/apps/web/src/app/favicon.ico +++ /dev/null diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index 42485461..e5a447dc 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -6,8 +6,33 @@ const roboto = Roboto({ weight: ["300", "400", "500"], subsets: ["latin"] }); const inter = Inter({ weight: ["300", "400", "500"], subsets: ["latin"] }); export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "Supermemory - Your second brain", + description: "Save your memories forever, build your own second brain.", + openGraph: { + images: [ + { + url: "https://supermemory.dhr.wtf/og-image.png", + width: 1200, + height: 630, + }, + ], + siteName: "Supermemory", + title: "Supermemory - Your second brain", + description: "Save your memories forever, build your own second brain.", + }, + twitter: { + card: "summary_large_image", + site: "https://supermemory.dhr.wtf", + creator: "@dhravyashah", + description: "Save your memories forever, build your own second brain.", + images: [ + { + url: "https://supermemory.dhr.wtf/og-image.png", + width: 1200, + height: 630, + }, + ], + }, }; export default function RootLayout({ |