aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDhravya Shah <[email protected]>2025-12-23 15:42:57 -0800
committerDhravya Shah <[email protected]>2025-12-23 15:42:57 -0800
commitc2a5cce02ca2c1dfcf2945aeb80f1885b0ad6e91 (patch)
treeadad08e6880491c5b88f13e26fcd26be364aeba4
parentadded a zero check before calculating maxDps, removed height and width from c... (diff)
downloadsupermemory-vrupak/main.tar.xz
supermemory-vrupak/main.zip
fix: show all memory relationsvrupak/main
-rw-r--r--apps/memory-graph-playground/src/app/page.tsx6
-rw-r--r--bun.lock17
-rw-r--r--packages/memory-graph/src/hooks/use-graph-data.ts124
3 files changed, 87 insertions, 60 deletions
diff --git a/apps/memory-graph-playground/src/app/page.tsx b/apps/memory-graph-playground/src/app/page.tsx
index 581557b6..f576c546 100644
--- a/apps/memory-graph-playground/src/app/page.tsx
+++ b/apps/memory-graph-playground/src/app/page.tsx
@@ -31,7 +31,9 @@ export default function Home() {
// State for slideshow
const [isSlideshowActive, setIsSlideshowActive] = useState(false)
- const [currentSlideshowNode, setCurrentSlideshowNode] = useState<string | null>(null)
+ const [currentSlideshowNode, setCurrentSlideshowNode] = useState<
+ string | null
+ >(null)
const PAGE_SIZE = 500
@@ -279,7 +281,7 @@ export default function Home() {
hasMore={hasMore}
loadMoreDocuments={loadMoreDocuments}
totalLoaded={documents.length}
- variant="consumer"
+ variant="console"
// Controlled space selection
selectedSpace={selectedSpace}
onSpaceChange={handleSpaceChange}
diff --git a/bun.lock b/bun.lock
index c31e4273..faaa685a 100644
--- a/bun.lock
+++ b/bun.lock
@@ -227,7 +227,6 @@
"@emotion/is-prop-valid": "^1.4.0",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-slot": "^1.2.4",
- "@supermemory/memory-graph": "^0.1.7",
"@vanilla-extract/css": "^1.17.4",
"@vanilla-extract/recipes": "^0.5.7",
"@vanilla-extract/sprinkles": "^1.6.5",
@@ -1457,7 +1456,7 @@
"@smithy/util-utf8": ["@smithy/[email protected]", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
- "@smithy/util-waiter": ["@smithy/[email protected]", "", { "dependencies": { "@smithy/abort-controller": "^2.2.0", "@smithy/types": "^2.12.0", "tslib": "^2.6.2" } }, "sha512-IHk53BVw6MPMi2Gsn+hCng8rFA3ZmR3Rk7GllxDUW9qFJl/hiSvskn7XldkECapQVkIg/1dHpMAxI9xSTaLLSA=="],
+ "@smithy/util-waiter": ["@smithy/[email protected]", "", { "dependencies": { "@smithy/abort-controller": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-Dbun99A3InifQdIrsXZ+QLcC0PGBPAdrl4cj1mTgJvyc9N2zf7QSxg8TBkzsCmGJdE3TLbO9ycwpY0EkWahQ/g=="],
"@smithy/uuid": ["@smithy/[email protected]", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
@@ -4411,13 +4410,9 @@
"@aws-sdk/client-cloudfront/@smithy/util-utf8": ["@smithy/[email protected]", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="],
- "@aws-sdk/client-cloudfront/fast-xml-parser": ["[email protected]", "", { "dependencies": { "strnum": "^1.0.5" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g=="],
-
- "@aws-sdk/client-dynamodb/@smithy/util-waiter": ["@smithy/[email protected]", "", { "dependencies": { "@smithy/abort-controller": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-Dbun99A3InifQdIrsXZ+QLcC0PGBPAdrl4cj1mTgJvyc9N2zf7QSxg8TBkzsCmGJdE3TLbO9ycwpY0EkWahQ/g=="],
+ "@aws-sdk/client-cloudfront/@smithy/util-waiter": ["@smithy/[email protected]", "", { "dependencies": { "@smithy/abort-controller": "^2.2.0", "@smithy/types": "^2.12.0", "tslib": "^2.6.2" } }, "sha512-IHk53BVw6MPMi2Gsn+hCng8rFA3ZmR3Rk7GllxDUW9qFJl/hiSvskn7XldkECapQVkIg/1dHpMAxI9xSTaLLSA=="],
- "@aws-sdk/client-lambda/@smithy/util-waiter": ["@smithy/[email protected]", "", { "dependencies": { "@smithy/abort-controller": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-Dbun99A3InifQdIrsXZ+QLcC0PGBPAdrl4cj1mTgJvyc9N2zf7QSxg8TBkzsCmGJdE3TLbO9ycwpY0EkWahQ/g=="],
-
- "@aws-sdk/client-s3/@smithy/util-waiter": ["@smithy/[email protected]", "", { "dependencies": { "@smithy/abort-controller": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-Dbun99A3InifQdIrsXZ+QLcC0PGBPAdrl4cj1mTgJvyc9N2zf7QSxg8TBkzsCmGJdE3TLbO9ycwpY0EkWahQ/g=="],
+ "@aws-sdk/client-cloudfront/fast-xml-parser": ["[email protected]", "", { "dependencies": { "strnum": "^1.0.5" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g=="],
"@aws-sdk/client-sts/@aws-crypto/sha256-browser": ["@aws-crypto/[email protected]", "", { "dependencies": { "@aws-crypto/ie11-detection": "^3.0.0", "@aws-crypto/sha256-js": "^3.0.0", "@aws-crypto/supports-web-crypto": "^3.0.0", "@aws-crypto/util": "^3.0.0", "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-locate-window": "^3.0.0", "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" } }, "sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ=="],
@@ -4715,10 +4710,6 @@
"@shikijs/core/hast-util-to-html": ["[email protected]", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="],
- "@smithy/util-waiter/@smithy/abort-controller": ["@smithy/[email protected]", "", { "dependencies": { "@smithy/types": "^2.12.0", "tslib": "^2.6.2" } }, "sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw=="],
-
- "@smithy/util-waiter/@smithy/types": ["@smithy/[email protected]", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw=="],
-
"@stoplight/better-ajv-errors/leven": ["[email protected]", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="],
"@stoplight/json/safe-stable-stringify": ["[email protected]", "", {}, "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw=="],
@@ -5249,6 +5240,8 @@
"@aws-sdk/client-cloudfront/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/[email protected]", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="],
+ "@aws-sdk/client-cloudfront/@smithy/util-waiter/@smithy/abort-controller": ["@smithy/[email protected]", "", { "dependencies": { "@smithy/types": "^2.12.0", "tslib": "^2.6.2" } }, "sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw=="],
+
"@aws-sdk/client-cloudfront/fast-xml-parser/strnum": ["[email protected]", "", {}, "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA=="],
"@aws-sdk/client-sts/@aws-crypto/sha256-browser/@aws-crypto/supports-web-crypto": ["@aws-crypto/[email protected]", "", { "dependencies": { "tslib": "^1.11.1" } }, "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg=="],
diff --git a/packages/memory-graph/src/hooks/use-graph-data.ts b/packages/memory-graph/src/hooks/use-graph-data.ts
index 4281742f..a33ddfe2 100644
--- a/packages/memory-graph/src/hooks/use-graph-data.ts
+++ b/packages/memory-graph/src/hooks/use-graph-data.ts
@@ -19,7 +19,16 @@ import type {
export function useGraphData(
data: DocumentsResponse | null,
selectedSpace: string,
- nodePositions: Map<string, { x: number; y: number; parentDocId?: string; offsetX?: number; offsetY?: number }>,
+ nodePositions: Map<
+ string,
+ {
+ x: number
+ y: number
+ parentDocId?: string
+ offsetX?: number
+ offsetY?: number
+ }
+ >,
draggingNodeId: string | null,
memoryLimit?: number,
maxNodes?: number,
@@ -60,35 +69,34 @@ export function useGraphData(
})
// Filter by space and prepare documents
- let processedDocs = sortedDocs
- .map((doc) => {
- let memories =
- selectedSpace === "all"
- ? doc.memoryEntries
- : doc.memoryEntries.filter(
- (memory) =>
- (memory.spaceContainerTag ?? memory.spaceId ?? "default") ===
- selectedSpace,
- )
-
- // Sort memories by relevance score (if available) or recency
- memories = memories.sort((a, b) => {
- // Prioritize sourceRelevanceScore if available
- if (a.sourceRelevanceScore != null && b.sourceRelevanceScore != null) {
- return b.sourceRelevanceScore - a.sourceRelevanceScore // Higher score first
- }
- // Fall back to most recent
- const dateA = new Date(a.updatedAt || a.createdAt).getTime()
- const dateB = new Date(b.updatedAt || b.createdAt).getTime()
- return dateB - dateA // Most recent first
- })
-
- return {
- ...doc,
- memoryEntries: memories,
+ let processedDocs = sortedDocs.map((doc) => {
+ let memories =
+ selectedSpace === "all"
+ ? doc.memoryEntries
+ : doc.memoryEntries.filter(
+ (memory) =>
+ (memory.spaceContainerTag ?? memory.spaceId ?? "default") ===
+ selectedSpace,
+ )
+
+ // Sort memories by relevance score (if available) or recency
+ memories = memories.sort((a, b) => {
+ // Prioritize sourceRelevanceScore if available
+ if (a.sourceRelevanceScore != null && b.sourceRelevanceScore != null) {
+ return b.sourceRelevanceScore - a.sourceRelevanceScore // Higher score first
}
+ // Fall back to most recent
+ const dateA = new Date(a.updatedAt || a.createdAt).getTime()
+ const dateB = new Date(b.updatedAt || b.createdAt).getTime()
+ return dateB - dateA // Most recent first
})
+ return {
+ ...doc,
+ memoryEntries: memories,
+ }
+ })
+
// Apply maxNodes limit using Option B (dynamic cap per document)
if (maxNodes && maxNodes > 0) {
const totalDocs = processedDocs.length
@@ -112,37 +120,57 @@ export function useGraphData(
// If we still have budget left, distribute remaining nodes to first docs
let remainingBudget = maxNodes - totalNodes
if (remainingBudget > 0) {
- for (let i = 0; i < processedDocs.length && remainingBudget > 0; i++) {
+ for (
+ let i = 0;
+ i < processedDocs.length && remainingBudget > 0;
+ i++
+ ) {
const doc = processedDocs[i]
if (!doc) continue
- const originalDoc = sortedDocs.find(d => d.id === doc.id)
+ const originalDoc = sortedDocs.find((d) => d.id === doc.id)
if (!originalDoc) continue
const currentMemCount = doc.memoryEntries.length
const originalMemCount = originalDoc.memoryEntries.filter(
- m => selectedSpace === "all" ||
- (m.spaceContainerTag ?? m.spaceId ?? "default") === selectedSpace
+ (m) =>
+ selectedSpace === "all" ||
+ (m.spaceContainerTag ?? m.spaceId ?? "default") ===
+ selectedSpace,
).length
// Can we add more memories to this doc?
const canAdd = originalMemCount - currentMemCount
if (canAdd > 0) {
const toAdd = Math.min(canAdd, remainingBudget)
- const additionalMems = doc.memoryEntries.slice(0, currentMemCount + toAdd)
+ const additionalMems = doc.memoryEntries.slice(
+ 0,
+ currentMemCount + toAdd,
+ )
processedDocs[i] = {
...doc,
memoryEntries: originalDoc.memoryEntries
- .filter(m => selectedSpace === "all" ||
- (m.spaceContainerTag ?? m.spaceId ?? "default") === selectedSpace)
+ .filter(
+ (m) =>
+ selectedSpace === "all" ||
+ (m.spaceContainerTag ?? m.spaceId ?? "default") ===
+ selectedSpace,
+ )
.sort((a, b) => {
- if (a.sourceRelevanceScore != null && b.sourceRelevanceScore != null) {
+ if (
+ a.sourceRelevanceScore != null &&
+ b.sourceRelevanceScore != null
+ ) {
return b.sourceRelevanceScore - a.sourceRelevanceScore
}
- const dateA = new Date(a.updatedAt || a.createdAt).getTime()
- const dateB = new Date(b.updatedAt || b.createdAt).getTime()
+ const dateA = new Date(
+ a.updatedAt || a.createdAt,
+ ).getTime()
+ const dateB = new Date(
+ b.updatedAt || b.createdAt,
+ ).getTime()
return dateB - dateA
})
- .slice(0, currentMemCount + toAdd)
+ .slice(0, currentMemCount + toAdd),
}
remainingBudget -= toAdd
}
@@ -238,8 +266,7 @@ export function useGraphData(
})
// Enhanced Layout with Space Separation
- const { centerX, centerY, clusterRadius } =
- LAYOUT_CONSTANTS
+ const { centerX, centerY, clusterRadius } = LAYOUT_CONSTANTS
/* 1. Build DOCUMENT nodes with space-aware clustering */
const documentNodes: GraphNode[] = []
@@ -255,8 +282,10 @@ export function useGraphData(
// Loose grid spacing - physics will organize it better
const spacing = 200
- const defaultX = centerX + (col - gridSize / 2) * spacing + (Math.random() - 0.5) * 50
- const defaultY = centerY + (row - gridSize / 2) * spacing + (Math.random() - 0.5) * 50
+ const defaultX =
+ centerX + (col - gridSize / 2) * spacing + (Math.random() - 0.5) * 50
+ const defaultY =
+ centerY + (row - gridSize / 2) * spacing + (Math.random() - 0.5) * 50
const customPos = nodePositions.get(doc.id)
@@ -318,9 +347,11 @@ export function useGraphData(
if (customMemPos) {
// If memory was manually positioned and has stored offset relative to parent
- if (customMemPos.parentDocId === docNode.id &&
+ if (
+ customMemPos.parentDocId === docNode.id &&
customMemPos.offsetX !== undefined &&
- customMemPos.offsetY !== undefined) {
+ customMemPos.offsetY !== undefined
+ ) {
// Apply the stored offset to the current document position
finalMemX = docNode.x + customMemPos.offsetX
finalMemY = docNode.y + customMemPos.offsetY
@@ -386,7 +417,8 @@ export function useGraphData(
data.documents.forEach((doc) => {
doc.memoryEntries.forEach((mem: MemoryEntry) => {
// Support both new object structure and legacy array/single parent fields
- let parentRelations: Record<string, MemoryRelation> = {}
+ let parentRelations: Record<string, MemoryRelation> =
+ mem.memoryRelations ?? ({} as Record<string, MemoryRelation>)
if (
mem.memoryRelations &&
@@ -436,4 +468,4 @@ export function useGraphData(
return { nodes: allNodes, edges: allEdges }
}, [data, filteredDocuments, nodePositions, draggingNodeId, similarityEdges])
-} \ No newline at end of file
+}