aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorDhravya Shah <[email protected]>2025-03-17 15:18:48 -0700
committerDhravya Shah <[email protected]>2025-03-17 15:18:48 -0700
commit8931c43295d593ffbec8431f5a2e4c97f02f5480 (patch)
tree39cb64a792cf1b24fe0b9487990dcf52451d6698 /apps
parentfix: tweets view (diff)
parentMerge pull request #339 from supermemoryai/hybrid-rag (diff)
downloadsupermemory-8931c43295d593ffbec8431f5a2e4c97f02f5480.tar.xz
supermemory-8931c43295d593ffbec8431f5a2e4c97f02f5480.zip
Merge branch 'main' of github.com:supermemoryai/supermemory
Diffstat (limited to 'apps')
-rw-r--r--apps/backend/src/components/landing.tsx2
-rw-r--r--apps/backend/src/routes/actions.ts109
-rw-r--r--apps/web/app/components/Landing/Hero.tsx15
-rw-r--r--apps/web/app/routes/extension.ts4
-rw-r--r--apps/web/app/routes/onboarding.index.tsx78
-rw-r--r--apps/web/app/routes/onboarding.privacy.tsx77
6 files changed, 55 insertions, 230 deletions
diff --git a/apps/backend/src/components/landing.tsx b/apps/backend/src/components/landing.tsx
index ae00a450..87bbdb69 100644
--- a/apps/backend/src/components/landing.tsx
+++ b/apps/backend/src/components/landing.tsx
@@ -194,7 +194,7 @@ export function LandingPage() {
</li>
<li>
<a
- href="https://discord.gg/supermemory"
+ href="https://discord.gg/b3BgKWpbtR"
target="_blank"
className="hover:text-white"
rel="noreferrer"
diff --git a/apps/backend/src/routes/actions.ts b/apps/backend/src/routes/actions.ts
index dd9311ed..706b87ba 100644
--- a/apps/backend/src/routes/actions.ts
+++ b/apps/backend/src/routes/actions.ts
@@ -131,10 +131,6 @@ const actions = fromHono(new Hono<{ Variables: Variables; Bindings: Env }>())
// Pre-compute the vector similarity expression
const vectorSimilarity = sql<number>`1 - (embeddings <=> ${JSON.stringify(embedding[0])}::vector)`;
- const textSearchRank = sql<number>`ts_rank_cd(
- to_tsvector('english', coalesce(${chunk.textContent}, '')),
- plainto_tsquery('english', ${queryText})
- )`;
// Get matching chunks with document info
const matchingChunks = await db
@@ -145,7 +141,6 @@ const actions = fromHono(new Hono<{ Variables: Variables; Bindings: Env }>())
orderInDocument: chunk.orderInDocument,
metadata: chunk.metadata,
similarity: vectorSimilarity,
- textRank: textSearchRank,
// Document fields
docId: documents.id,
docUuid: documents.uuid,
@@ -159,16 +154,10 @@ const actions = fromHono(new Hono<{ Variables: Variables; Bindings: Env }>())
.from(chunk)
.innerJoin(documents, eq(chunk.documentId, documents.id))
.where(
- and(eq(documents.userId, user.id), sql`${vectorSimilarity} > 0.5`)
+ and(eq(documents.userId, user.id), sql`${vectorSimilarity} > 0.3`)
)
- .orderBy(
- desc(sql<number>`(
- 0.6 * ${vectorSimilarity} +
- 0.25 * ${textSearchRank} +
- 0.15 * (1.0 / (1.0 + extract(epoch from age(${documents.updatedAt})) / (90 * 24 * 60 * 60)))
- )::float`)
- )
- .limit(15);
+ .orderBy(desc(vectorSimilarity))
+ .limit(25);
// Get unique document IDs from matching chunks
const uniqueDocIds = [
@@ -201,9 +190,9 @@ const actions = fromHono(new Hono<{ Variables: Variables; Bindings: Env }>())
const docChunks = chunksByDocument.get(match.documentId) || [];
const matchIndex = docChunks.findIndex((c) => c.id === match.chunkId);
- // Get surrounding chunks (1 before and 1 after)
- const start = Math.max(0, matchIndex - 1);
- const end = Math.min(docChunks.length, matchIndex + 2);
+ // Get surrounding chunks (2 before and 2 after for more context)
+ const start = Math.max(0, matchIndex - 2);
+ const end = Math.min(docChunks.length, matchIndex + 3);
const relevantChunks = docChunks.slice(start, end);
return {
@@ -224,34 +213,23 @@ const actions = fromHono(new Hono<{ Variables: Variables; Bindings: Env }>())
};
});
- // Remove duplicates based on document ID
- const uniqueResults = contextualResults.reduce(
- (acc, current) => {
- const existingDoc = acc.find((doc) => doc.id === current.id);
- if (!existingDoc) {
- acc.push(current);
- } else if (current.similarity > existingDoc.similarity) {
- // Replace if current match is better
- const index = acc.findIndex((doc) => doc.id === current.id);
- acc[index] = current;
- }
- return acc;
- },
- [] as typeof contextualResults
- );
+ // Sort by similarity and take top results
+ const topResults = contextualResults
+ .sort((a, b) => b.similarity - a.similarity)
+ .slice(0, 10);
- data.appendMessageAnnotation(uniqueResults);
+ data.appendMessageAnnotation(topResults);
if (lastUserMessage) {
lastUserMessage.content =
typeof lastUserMessage.content === "string"
? lastUserMessage.content +
- `<context>${JSON.stringify(uniqueResults)}</context>`
+ `<context>${JSON.stringify(topResults)}</context>`
: [
...lastUserMessage.content,
{
type: "text",
- text: `<context>${JSON.stringify(uniqueResults)}</context>`,
+ text: `<context>${JSON.stringify(topResults)}</context>`,
},
];
coreMessages[coreMessages.length - 1] = lastUserMessage;
@@ -310,7 +288,7 @@ const actions = fromHono(new Hono<{ Variables: Variables; Bindings: Env }>())
role: "assistant",
content:
completion.text +
- `<context>[${JSON.stringify(uniqueResults)}]</context>`,
+ `<context>[${JSON.stringify(topResults)}]</context>`,
},
];
@@ -602,14 +580,10 @@ const actions = fromHono(new Hono<{ Variables: Variables; Bindings: Env }>())
);
}
- // Pre-compute the vector similarity expression to avoid multiple calculations
+ // Pre-compute the vector similarity expression
const vectorSimilarity = sql<number>`1 - (embeddings <=> ${JSON.stringify(embeddings.data[0])}::vector)`;
- const textSearchRank = sql<number>`ts_rank_cd(
- to_tsvector('english', coalesce(${chunk.textContent}, '')),
- plainto_tsquery('english', ${query})
- )`;
- // First get the top matching chunks
+ // Get matching chunks
const results = await db
.select({
chunkId: chunk.id,
@@ -618,7 +592,6 @@ const actions = fromHono(new Hono<{ Variables: Variables; Bindings: Env }>())
orderInDocument: chunk.orderInDocument,
metadata: chunk.metadata,
similarity: vectorSimilarity,
- textRank: textSearchRank,
// Document fields
docUuid: documents.uuid,
docContent: documents.content,
@@ -657,13 +630,7 @@ const actions = fromHono(new Hono<{ Variables: Variables; Bindings: Env }>())
: [])
)
)
- .orderBy(
- desc(sql<number>`(
- 0.6 * ${vectorSimilarity} +
- 0.25 * ${textSearchRank} +
- 0.15 * (1.0 / (1.0 + extract(epoch from age(${documents.updatedAt})) / (90 * 24 * 60 * 60)))
- )::float`)
- )
+ .orderBy(desc(vectorSimilarity))
.limit(limit);
// Group results by document and take the best matching chunk
@@ -679,26 +646,28 @@ const actions = fromHono(new Hono<{ Variables: Variables; Bindings: Env }>())
}
// Convert back to array and format response
- const finalResults = Array.from(documentResults.values()).map((r) => ({
- id: r.documentId,
- uuid: r.docUuid,
- content: r.docContent,
- type: r.docType,
- url: r.docUrl,
- title: r.docTitle,
- createdAt: r.docCreatedAt,
- updatedAt: r.docUpdatedAt,
- userId: r.docUserId,
- description: r.docDescription,
- ogImage: r.docOgImage,
- similarity: Number(r.similarity.toFixed(4)),
- matchingChunk: {
- id: r.chunkId,
- content: r.textContent,
- orderInDocument: r.orderInDocument,
- metadata: r.metadata,
- },
- }));
+ const finalResults = Array.from(documentResults.values())
+ .sort((a, b) => b.similarity - a.similarity)
+ .map((r) => ({
+ id: r.documentId,
+ uuid: r.docUuid,
+ content: r.docContent,
+ type: r.docType,
+ url: r.docUrl,
+ title: r.docTitle,
+ createdAt: r.docCreatedAt,
+ updatedAt: r.docUpdatedAt,
+ userId: r.docUserId,
+ description: r.docDescription,
+ ogImage: r.docOgImage,
+ similarity: Number(r.similarity.toFixed(4)),
+ matchingChunk: {
+ id: r.chunkId,
+ content: r.textContent,
+ orderInDocument: r.orderInDocument,
+ metadata: r.metadata,
+ },
+ }));
return c.json({ results: finalResults });
} catch (error) {
diff --git a/apps/web/app/components/Landing/Hero.tsx b/apps/web/app/components/Landing/Hero.tsx
index 06d82dfb..353d0211 100644
--- a/apps/web/app/components/Landing/Hero.tsx
+++ b/apps/web/app/components/Landing/Hero.tsx
@@ -77,7 +77,10 @@ export default function Hero() {
</Popover>
*/}
- <a href="https://docs.supermemory.ai" className="text-gray-600 hover:text-gray-900 transition-colors">
+ <a
+ href="https://docs.supermemory.ai"
+ className="text-gray-600 hover:text-gray-900 transition-colors"
+ >
Docs
</a>
</nav>
@@ -86,10 +89,16 @@ export default function Hero() {
{/* Right section */}
<div className="flex items-center space-x-6">
<div className="hidden sm:flex items-center space-x-6">
- <a href="#" className="text-gray-600 hover:text-gray-900 transition-colors">
+ <a
+ href="https://git.new/memory"
+ className="text-gray-600 hover:text-gray-900 transition-colors"
+ >
<GithubIcon className="h-6 w-6" />
</a>
- <a href="#" className="text-gray-600 hover:text-gray-900 transition-colors">
+ <a
+ href="https://discord.gg/b3BgKWpbtR"
+ className="text-gray-600 hover:text-gray-900 transition-colors"
+ >
<DiscordIcon className="h-6 w-6" />
</a>
</div>
diff --git a/apps/web/app/routes/extension.ts b/apps/web/app/routes/extension.ts
index 0a44b972..f20d7cc3 100644
--- a/apps/web/app/routes/extension.ts
+++ b/apps/web/app/routes/extension.ts
@@ -1,5 +1,7 @@
import { LoaderFunctionArgs, redirect } from "@remix-run/cloudflare";
export async function loader({ context }: LoaderFunctionArgs) {
- return redirect("https://chromewebstore.google.com/detail/supermemory/afpgkkipfdpeaflnpoaffkcankadgjfc?hl=en");
+ return redirect(
+ "https://chromewebstore.google.com/detail/supermemory/afpgkkipfdpeaflnpoaffkcankadgjfc?hl=en",
+ );
}
diff --git a/apps/web/app/routes/onboarding.index.tsx b/apps/web/app/routes/onboarding.index.tsx
index 5ffff732..30ff8d37 100644
--- a/apps/web/app/routes/onboarding.index.tsx
+++ b/apps/web/app/routes/onboarding.index.tsx
@@ -48,84 +48,6 @@ export default function Onboarding() {
animate={{ opacity: 1 }}
className="flex flex-col min-h-screen items-center pt-40 relative overflow-hidden bg-gradient-to-b from-gray-900 to-gray-800 bg-opacity-40"
>
- {/* Neural network background pattern */}
- <div className="absolute inset-0 overflow-hidden">
- {/* Subtle gradient orbs */}
- {[...Array(4)].map((_, i) => (
- <motion.div
- key={`orb-${i}`}
- className="absolute rounded-full blur-3xl opacity-20"
- style={{
- background: `radial-gradient(circle, ${
- i % 2 === 0 ? "#3b82f6" : "#4f46e5"
- } 0%, transparent 70%)`,
- width: `${Math.random() * 300 + 200}px`,
- height: `${Math.random() * 300 + 200}px`,
- }}
- animate={{
- x: [Math.random() * window.innerWidth, Math.random() * window.innerWidth],
- y: [Math.random() * window.innerHeight, Math.random() * window.innerHeight],
- }}
- transition={{
- duration: 25,
- repeat: Infinity,
- repeatType: "reverse",
- ease: "easeInOut",
- }}
- />
- ))}
-
- {/* Neurons */}
- {[...Array(30)].map((_, i) => (
- <motion.div
- key={i}
- className="absolute w-3 h-3 bg-blue-400/30 rounded-full"
- initial={{
- x: Math.random() * window.innerWidth,
- y: Math.random() * window.innerHeight,
- scale: Math.random() * 0.5 + 0.5,
- }}
- animate={{
- x: Math.random() * window.innerWidth,
- y: Math.random() * window.innerHeight,
- scale: [null, 1.2, 1],
- }}
- transition={{
- duration: 10 + Math.random() * 5,
- repeat: Infinity,
- ease: "linear",
- delay: Math.random() * 2,
- }}
- />
- ))}
-
- {/* Synaptic connections */}
- {[...Array(40)].map((_, i) => (
- <motion.div
- key={`line-${i}`}
- className="absolute h-[1px] bg-gradient-to-r from-blue-400/20 to-transparent"
- style={{
- width: `${Math.random() * 200 + 100}px`,
- transform: `rotate(${Math.random() * 360}deg)`,
- }}
- initial={{
- x: Math.random() * window.innerWidth,
- y: Math.random() * window.innerHeight,
- opacity: 0.1,
- }}
- animate={{
- opacity: [0.1, 0.3, 0.1],
- }}
- transition={{
- duration: 4 + Math.random() * 2,
- repeat: Infinity,
- ease: "easeInOut",
- delay: Math.random() * 2,
- }}
- />
- ))}
- </div>
-
{/* Logo */}
<motion.div
initial={{ y: 20, opacity: 0 }}
diff --git a/apps/web/app/routes/onboarding.privacy.tsx b/apps/web/app/routes/onboarding.privacy.tsx
index 5a03c998..e043bf63 100644
--- a/apps/web/app/routes/onboarding.privacy.tsx
+++ b/apps/web/app/routes/onboarding.privacy.tsx
@@ -27,83 +27,6 @@ export default function Onboarding() {
animate={{ opacity: 1 }}
className="flex flex-col min-h-screen items-center pt-20 relative overflow-hidden bg-gradient-to-b from-gray-900 to-gray-800 bg-opacity-40"
>
- {/* Neural network background pattern */}
- <div className="absolute inset-0 overflow-hidden pointer-events-none">
- {/* Subtle gradient orbs */}
- {[...Array(4)].map((_, i) => (
- <motion.div
- key={`orb-${i}`}
- className="absolute rounded-full blur-3xl opacity-20"
- style={{
- background: `radial-gradient(circle, ${
- i % 2 === 0 ? "#3b82f6" : "#4f46e5"
- } 0%, transparent 70%)`,
- width: `${Math.random() * 300 + 200}px`,
- height: `${Math.random() * 300 + 200}px`,
- }}
- animate={{
- x: [Math.random() * window.innerWidth, Math.random() * window.innerWidth],
- y: [Math.random() * window.innerHeight, Math.random() * window.innerHeight],
- }}
- transition={{
- duration: 25,
- repeat: Infinity,
- repeatType: "reverse",
- ease: "easeInOut",
- }}
- />
- ))}
-
- {/* Neurons */}
- {[...Array(30)].map((_, i) => (
- <motion.div
- key={i}
- className="absolute w-3 h-3 bg-blue-400/30 rounded-full"
- initial={{
- x: Math.random() * window.innerWidth,
- y: Math.random() * window.innerHeight,
- scale: Math.random() * 0.5 + 0.5,
- }}
- animate={{
- x: Math.random() * window.innerWidth,
- y: Math.random() * window.innerHeight,
- scale: [null, 1.2, 1],
- }}
- transition={{
- duration: 10 + Math.random() * 5,
- repeat: Infinity,
- ease: "linear",
- delay: Math.random() * 2,
- }}
- />
- ))}
-
- {/* Synaptic connections */}
- {[...Array(40)].map((_, i) => (
- <motion.div
- key={`line-${i}`}
- className="absolute h-[1px] bg-gradient-to-r from-blue-400/20 to-transparent"
- style={{
- width: `${Math.random() * 200 + 100}px`,
- transform: `rotate(${Math.random() * 360}deg)`,
- }}
- initial={{
- x: Math.random() * window.innerWidth,
- y: Math.random() * window.innerHeight,
- opacity: 0.1,
- }}
- animate={{
- opacity: [0.1, 0.3, 0.1],
- }}
- transition={{
- duration: 4 + Math.random() * 2,
- repeat: Infinity,
- ease: "easeInOut",
- delay: Math.random() * 2,
- }}
- />
- ))}
- </div>
{/* Logo */}
<motion.div