Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ yarn-error.log*
# Misc
.DS_Store
*.pem

.claude
.venv
__pycache__
76 changes: 70 additions & 6 deletions apps/memory-graph-playground/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export default function Home() {
// State for controlled space selection
const [selectedSpace, setSelectedSpace] = useState<string>("all")

// State for slideshow
const [isSlideshowActive, setIsSlideshowActive] = useState(false)
const [currentSlideshowNode, setCurrentSlideshowNode] = useState<string | null>(null)

const PAGE_SIZE = 500

const fetchDocuments = useCallback(
Expand Down Expand Up @@ -109,6 +113,23 @@ export default function Home() {
setSelectedSpace("all")
}

// Toggle slideshow
const handleToggleSlideshow = () => {
setIsSlideshowActive((prev) => !prev)
}

// Handle slideshow node change
const handleSlideshowNodeChange = useCallback((nodeId: string | null) => {
// Track which node is being shown in slideshow
setCurrentSlideshowNode(nodeId)
console.log("Slideshow showing node:", nodeId)
}, [])

// Handle slideshow stop (when user clicks outside)
const handleSlideshowStop = useCallback(() => {
setIsSlideshowActive(false)
}, [])

return (
<div className="flex flex-col h-screen bg-zinc-950">
{/* Header */}
Expand Down Expand Up @@ -158,12 +179,49 @@ export default function Home() {
</span>
</div>
</div>
<button
onClick={handleReset}
className="rounded-lg border border-zinc-700 px-3 py-1 text-xs font-medium text-zinc-300 transition-colors hover:bg-zinc-800"
>
Reset Filters
</button>
<div className="flex items-center gap-3">
<button
onClick={handleToggleSlideshow}
className={`rounded-lg px-3 py-1.5 text-xs font-medium transition-colors flex items-center gap-1.5 ${
isSlideshowActive
? "bg-blue-600 text-white hover:bg-blue-700"
: "border border-zinc-700 text-zinc-300 hover:bg-zinc-800"
}`}
>
{isSlideshowActive ? (
<>
<svg
width="12"
height="12"
viewBox="0 0 24 24"
fill="currentColor"
>
<rect x="6" y="6" width="12" height="12" />
</svg>
Slideshow
</>
) : (
<>
<svg
width="12"
height="12"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M8 5v14l11-7z" />
</svg>
Slideshow
</>
)}
</button>
<div className="h-6 w-px bg-zinc-700" />
<button
onClick={handleReset}
className="rounded-lg border border-zinc-700 px-3 py-1.5 text-xs font-medium text-zinc-300 transition-colors hover:bg-zinc-800"
>
Reset Filters
</button>
</div>
</div>
</div>
)}
Expand Down Expand Up @@ -225,6 +283,12 @@ export default function Home() {
// Controlled space selection
selectedSpace={selectedSpace}
onSpaceChange={handleSpaceChange}
// Node limit - prevents performance issues with large graphs
maxNodes={500}
// Slideshow control
isSlideshowActive={isSlideshowActive}
onSlideshowNodeChange={handleSlideshowNodeChange}
onSlideshowStop={handleSlideshowStop}
>
<div className="flex h-full items-center justify-center">
<p className="text-zinc-400">
Expand Down
462 changes: 129 additions & 333 deletions bun.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"@scalar/hono-api-reference": "^0.9.11",
"@vanilla-extract/recipes": "^0.5.7",
"ai": "^5.0.59",
"alchemy": "^0.55.2",
"alchemy": "^0.81.4",
"atmn": "^0.0.16",
"better-auth": "^1.3.3",
"boxen": "^8.0.1",
Expand Down Expand Up @@ -61,7 +61,7 @@
"drizzle-kit": "^0.31.4",
"turbo": "^2.5.4",
"typescript": "5.8.3",
"wrangler": "4.22.0"
"wrangler": "^4.42.2"
},
"workerd": {
"import": "./esm/index.mjs",
Expand Down
103 changes: 103 additions & 0 deletions packages/memory-graph/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Memory Graph Changelog

## Development Setup

To test changes, run these commands in separate terminals:

**Terminal 1** - Install the required dependencies:
```bash
bun install
```

**Terminal 1** - Build memory-graph in watch mode:
```bash
cd packages/memory-graph && bun run dev
```

**Terminal 2** - Run the playground:
```bash
cd apps/memory-graph-playground && bun run dev
```

Then open http://localhost:3000 in your browser.

---

### Features

#### Slideshow Mode
Auto-cycling through nodes with smooth animations and physics simulation
- Random node selection every 3.5s (avoids consecutive duplicates)
- Smooth pan-to-node animation with automatic popover
- Brief physics pulse (1s) on each selection
- Background dimming animation
- Single-click to stop

#### Node Popover with Background Dimming
Floating popover with smart positioning and focus dimming effect
- Smooth 1.5s cubic ease-out dimming animation
- Non-selected nodes: 20% opacity, unconnected edges: 10% opacity
- Smart edge detection with 20px gap from node
- Auto-flips to avoid viewport edges
- Close via backdrop click, X button, or Escape key
- Shows: title, summary, type, memory count, URL, date, ID

#### Document Type Icons
Canvas-rendered icons centered on document cards
- Supported: TXT, PDF, MD, DOC/DOCX, RTF, CSV, JSON
- Scales with card size (40% of height)
- Only renders when zoomed in

#### Physics-Driven Layout
Simplified initial positioning, letting physics create natural layouts
- Simple grid with random offsets (no concentric rings)
- 50 quick pre-ticks + smooth animation
- Eliminates teleportation on node interaction
- Faster, non-blocking initial render

#### Updated Color Scheme
Refined palette for better contrast and readability

### Bug Fixes

#### Edge Viewport Culling
Fixed edges disappearing during zoom/pan
- Now checks both X and Y axis bounds
- Only culls when BOTH endpoints off-screen in same direction
- 100px margin on all sides

#### Memory Nodes Follow Parents
Memory nodes now move with parent documents when dragged
- Store relative offset instead of absolute position
- Automatically repositions based on parent location

### Performance

#### k-NN Similarity Algorithm
Reduced from O(n²) to O(n·k)
- 3x faster: ~50ms → ~17ms for 100 docs
- 4,950 → 1,500 comparisons for 100 docs
- Separated into own memo (doesn't recalculate on UI interactions)

#### Memory Leak Fix
NodeCache now cleans up deleted nodes properly

#### Race Condition Fix
Atomic node/edge updates eliminate NaN positions

#### Canvas Rendering Optimizations
Reduced per-frame overhead and improved rendering efficiency
- Spatial grid for hit detection
- Batched edge rendering by type (fewer canvas state changes)
- Canvas quality settings initialized once instead of every frame
- Optimized render key using fast hash instead of string concatenation
- Memoized nodeMap to avoid rebuilding every frame

#### Node Limiting & Memory Management
Smart memory limiting prevents performance issues with large datasets
- `maxNodes` prop limits total memory nodes (default: 500 in playground)
- Dynamic per-document cap distributes budget across documents
- Prioritizes recent memories and high-relevance scores
- k-NN similarity limit reduced from 15 to 10 connections per document

---
1 change: 1 addition & 0 deletions packages/memory-graph/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"@vanilla-extract/css": "^1.17.4",
"@vanilla-extract/recipes": "^0.5.7",
"@vanilla-extract/sprinkles": "^1.6.5",
"d3-force": "^3.0.0",
"lucide-react": "^0.552.0",
"motion": "^12.23.24"
},
Expand Down
Loading
Loading