Personal AI Memory: Local-First RAG Extension for LLM
Your conversations, remembered. Privately.
๐ ็น้ซไธญๆ | ็ฎไฝไธญๆ | English | ๆฅๆฌ่ช | ํ๊ตญ์ด | Espaรฑol | Franรงais | Deutsch
A Chrome extension that silently captures your ChatGPT / Claude / Gemini / Perplexity / Grok conversations and stores them as private, locally-indexed semantic memories โ with a one-click Recall button to inject relevant context back into new chats.
100% local. No cloud. No server. No account required.
Demo
https://github.com/user-attachments/assets/d2aef66f-30b0-459c-8a92-64b8f5617bf6
Installation
For Users โ Chrome Web Store
Install directly from the Chrome Web Store.
Note: The Chrome Web Store version may lag behind the latest release. For the newest features, download the latest
.zipfrom the Releases page and load it manually (see below).
Manual Install from Release
- Go to the Releases page and download the latest
.zip - Unzip the file
- Open Chrome โ
chrome://extensions/ - Toggle Developer mode on (top-right)
- Click Load unpacked โ select the unzipped folder
For Developers โ Build from Source
Requirements: Node.js 18+, pnpm (npm install -g pnpm), Chrome / Edge (MV3)
# Fork this repository to your own GitHub account
git clone https://github.com/<your-github-username>/personal-ai-memory.git
cd personal-ai-memory
pnpm install
# Development mode โ auto-rebuilds on every save
pnpm dev
Then load build/chrome-mv3-dev/ via Load unpacked in chrome://extensions/.
# Production build
pnpm build
# output: build/chrome-mv3-prod/
After any code change: click Reload on the AI Memory card, then refresh open AI tabs.
Features at a Glance
| Feature | Details |
|---|---|
| Passive capture | Auto-intercepts ChatGPT / Claude / Gemini / Perplexity / Grok โ no setup, no clicks. Just visit the page and existing conversations are captured automatically. |
| Hybrid search | Vector (time-decay) + BM25, fused with RRF for best-of-both results |
| One-click Recall | Injects relevant memories as a RAG prompt into ChatGPT, Claude, Gemini, Grok, and Perplexity |
| Local backup | Export / import full backup as JSON (embeddings included) |
| Favourite Prompts | Save, autocomplete (Trie), organise into drag-and-drop folders |
| Floating panel | Draggable memory panel on every AI site |
| 8 UI languages | zh-TW ยท zh-CN ยท en ยท ja ยท ko ยท es ยท fr ยท de โ auto-detected |
| Dark / Light theme | Apple Liquid Glass-inspired toggle |
Supported platforms: ChatGPT (chat.openai.com / chatgpt.com) ยท Gemini (gemini.google.com) ยท Claude (claude.ai) ยท Perplexity (perplexity.ai) ยท Grok (grok.com)
How It Works
You chat on ChatGPT / Claude / Gemini / Perplexity / Grok
โ (extension captures silently in background)
โผ
Memories stored locally in IndexedDB
+ semantic embedding vector (ONNX, runs in browser)
+ keyword index (MiniSearch / BM25, in Service Worker memory)
โ
โ Later โ you start a new chat
โผ
Click ๐ง Recall next to the input box on any supported AI site
โ
โผ
Hybrid search:
Route A โ vector similarity ร time-decay (recent = higher weight)
Route B โ BM25 keyword search (prefix matching)
Fusion โ Reciprocal Rank Fusion (RRF)
โ
โผ
Top-k memories injected as RAG context into the input box
AI now has your history as background knowledge
Search Algorithm (detail)
Route A โ Vector Search + Time-Decay
query โ Float32Array embedding (ONNX, Offscreen Document)
for each record: dot_product(q, r.embedding) ร exp(-0.01 ร daysOld)
group by parentId โ keep max decayed score per group
sort descending โ vectorRanked[]
(half-life โ 69 days, ฮป = 0.01)
Route B โ Keyword search (MiniSearch / BM25)
miniSearch.search(query, { prefix: true })
prefix matching: "py" finds "python", "react" finds "reactivity"
sort by BM25 score โ kwRanked[]
Fusion โ Reciprocal Rank Fusion (RRF, k = 60)
rrfScore[key] += 1 / (60 + rank) for each list
sum both lists โ sort desc โ top-k โ merge chunks โ SearchResult[]
Fallback: if embedding fails, keyword-only results are returned; if no keyword matches, vector-only results are returned.
How to Export Chat History?
ChatGPT
- Log in to your ChatGPT account and go to the main screen.
- Click your profile picture or name in the corner to open the menu.
- Select Settings.
- Go to the Data controls tab.
- Find Export data and click Export.
- Click Confirm export in the confirmation window.
- You will receive an email with a download link (may take up to 24 hours).
- Download the ZIP file. After extracting, the chat history file is
conversations-00x.json.
Gemini
Export via Google Takeout:
- Go to Google Takeout and sign in.
- Click Deselect all at the top.
- Scroll down and check My Activity (NOT
Gemini Apps). - Click Multiple formats below that section.
- Change the first activity format from HTML to JSON, click OK.
- Click Next step โ choose delivery method โ Create export.
- Wait for the email. After extracting, the file is
my activity.json.
Claude
- Go to https://claude.ai/settings/data-privacy-controls.
- Click Export data.
- Wait for the email with the download link.
- After extracting, the chat history file is
conversations.json.
Perplexity
Perplexity does not support user data export. Each conversation must be visited individually to be captured by the extension.
Grok
- Go to https://grok.com.
- Click your profile picture (bottom-left) โ Settings โ Data controls.
- Click Export Account Data.
- Wait several hours for the download link email.
- After extracting, the file is
prod-grok-backend.json.
Privacy & Security
This extension intercepts your AI conversations. Here is exactly what it does and does not do:
| Question | Answer |
|---|---|
| Where is data stored? | Browser-local IndexedDB only (AIMemoryDB) โ never leaves your device |
| Does it make network requests? | Conversation data never leaves your device. Two types of optional network requests occur: (1) ONNX model download on first run; (2) anonymous usage analytics (if enabled) โ event names only, no conversation content, no URLs, no personal data. Analytics can be disabled in Settings โ Privacy. |
| Can websites see my memories? | No. Data is isolated in the extension's storage, inaccessible to page scripts. |
| Can I delete my data? | Yes โ soft-delete individual records from the floating panel, or clear all via DevTools โ IndexedDB. |
Treat this extension like a local diary. It sees everything you type and receive on supported AI sites. Review the source code if you have concerns.
Tech Stack
| Layer | Technology |
|---|---|
| Extension framework | Plasmo (Chrome MV3) |
| UI | React 18 + custom Theme Tokens |
| Persistence | IndexedDB via Dexie |
| Vector search | Transformers.js ONNX โ paraphrase-multilingual-MiniLM-L12-v2 |
| Keyword search | MiniSearch (BM25, in-memory) |
| Language | TypeScript |
๐ Project Structure
src/
โโโ background/
โ โโโ index.ts Message router ยท capture handler ยท MiniSearch sync
โ โโโ search.ts Hybrid search engine (vector ร decay + BM25 + RRF)
โ โโโ db.ts IndexedDB (Dexie) operations
โ โโโ embedding.ts ONNX model name / version constants
โ โโโ injector.ts MAIN-world fetch/XHR interceptor (injected into page)
โ โโโ chunking.ts Text chunking (500-char segments, 75-char overlap)
โ โโโ domSync.ts DOM-based conversation sync
โ โโโ offscreen.ts Offscreen document message handler
โ โโโ perplexityBgFetch.ts Perplexity background fetch helper
โ โโโ syncEmbeddings.ts Embedding sync utilities
โ โโโ adapters/
โ โโโ chatgpt.ts ChatGPT SSE delta-v1 parser
โ โโโ claude.ts Claude SSE parser
โ โโโ gemini.ts Gemini XHR StreamGenerate parser + passive capture
โ โโโ perplexity.ts Perplexity SSE parser
โ โโโ grok.ts Grok SSE parser
โโโ contents/
โ โโโ interceptor.ts ISOLATED-world bridge + <title> MutationObserver
โ โโโ memory-float-ui.tsx Floating panel content script entry point
โ โโโ chatgpt-injector.tsx ChatGPT Recall button + RAG prompt
โ โโโ claude-injector.tsx Claude Recall button
โ โโโ gemini-injector.tsx Gemini passive capture + Recall button
โ โโโ grok-injector.tsx Grok Recall button
โ โโโ perplexity-injector.tsx Perplexity Recall button
โโโ importers/
โ โโโ base.ts Base importer interface
โ โโโ chatgptConversations.ts ChatGPT JSON importer
โ โโโ claudeConversations.ts Claude JSON importer
โ โโโ geminiTakeout.ts Gemini Takeout importer
โ โโโ grokConversations.ts Grok JSON importer
โ โโโ index.ts Importer registry
โโโ tabs/
โ โโโ offscreen.tsx ONNX inference (Offscreen Document โ needs DOM)
โโโ popup/
โ โโโ index.tsx Popup root โ sliding panel navigation
โ โโโ components/
โ โโโ FloatingMemoryPanel.tsx Draggable floating panel (logo + panel)
โ โโโ MemoryMenuContent.tsx Memory menu content (sidebar / popup)
โ โโโ MemoryTableView.tsx Memory list grouped by session
โ โโโ ImportView.tsx JSON import UI
โ โโโ ExportView.tsx JSON export UI
โ โโโ FavoritePromptsSection.tsx Trie autocomplete prompts
โ โโโ FolderView.tsx Drag-and-drop folder management
โโโ utils/
โ โโโ chrome-storage.ts Shared chrome.storage.local helpers (load/save/subscribe)
โ โโโ rag.ts RAG prompt formatting
โ โโโ recall-button.ts Recall button creation and injection
โ โโโ recall-helpers.ts Shared recall utilities
โ โโโ trie.ts Trie data structure for autocomplete
โ โโโ message-passing.ts Type-safe Chrome message passing
โ โโโ onboarding-highlight.ts Onboarding step highlight helpers
โโโ i18n/
โ โโโ translations.ts 8-language string map
โ โโโ LanguageContext.tsx Language switching (chrome.storage โ syncs across tabs)
โ โโโ ThemeContext.tsx Dark/light theme (chrome.storage โ syncs across tabs)
โ โโโ lang-storage.ts Language persistence helpers
โโโ types/
โโโ memory.ts MemoryRecord ยท SearchResult interfaces
โโโ messages.ts All Chrome message type definitions
Debugging & Testing
| Target | How to reach it |
|---|---|
| Background Service Worker | chrome://extensions/ โ AI Memory โ Service worker |
| Popup | Right-click extension icon โ Inspect popup |
| Content scripts | DevTools โ Sources โ Content scripts |
| IndexedDB | DevTools โ Application โ Storage โ IndexedDB โ AIMemoryDB |
| Manual search test | Service Worker console: testSearch('keyword', 5) |
pnpm test # Unit tests (Vitest)
pnpm test:integration # Integration tests
pnpm test:e2e # E2E tests (Playwright โ run pnpm build first)
Changelog
See CHANGELOG.md for the full version history.
Contributing
PRs and issues are welcome! Please open an issue to discuss significant changes before submitting a PR.
- Bug reports: open an issue
- Feature requests: open an issue