Skip to content

marswangyang/personal-ai-memory

Repository files navigation

Personal AI Memory: Local-First RAG Extension for LLM

Your conversations, remembered. Privately.

License Chrome Web Store Chrome Web Store Users Manifest V3 ChatGPT Claude Gemini Perplexity Grok PRs Welcome

🌐 繁體中文 | 简体中文 | English | 日本語 | 한국어 | Español | Français | Deutsch

Personal AI Memory - Captures and stores your chat from various AI platforms | Product Hunt


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

output.mp4

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 .zip from the Releases page and load it manually (see below).

Manual Install from Release

  1. Go to the Releases page and download the latest .zip
  2. Unzip the file
  3. Open Chrome → chrome://extensions/
  4. Toggle Developer mode on (top-right)
  5. 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 and Claude
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 ChatGPT / Claude input
        │
        ▼
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

  1. Log in to your ChatGPT account and go to the main screen.
  2. Click your profile picture or name in the corner to open the menu.
  3. Select Settings.
  4. Go to the Data controls tab.
  5. Find Export data and click Export.
  6. Click Confirm export in the confirmation window.
  7. You will receive an email with a download link (may take up to 24 hours).
  8. Download the ZIP file. After extracting, the chat history file is conversations-00x.json.

Gemini

Export via Google Takeout:

  1. Go to Google Takeout and sign in.
  2. Click Deselect all at the top.
  3. Scroll down and check My Activity (NOT Gemini Apps).
  4. Click Multiple formats below that section.
  5. Change the first activity format from HTML to JSON, click OK.
  6. Click Next step → choose delivery method → Create export.
  7. Wait for the email. After extracting, the file is my activity.json.

Claude

  1. Go to https://claude.ai/settings/data-privacy-controls.
  2. Click Export data.
  3. Wait for the email with the download link.
  4. 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

  1. Go to https://grok.com.
  2. Click your profile picture (bottom-left) → SettingsData controls.
  3. Click Export Account Data.
  4. Wait several hours for the download link email.
  5. 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? Only once — to download the ONNX embedding model on first run. No conversation data is ever uploaded.
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)
│   └── 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   Recall button injection + RAG prompt assembly
│   ├── gemini-injector.tsx    Gemini passive capture + Recall button
│   └── grok-injector.tsx      Grok passive capture
├── tabs/
│   └── offscreen.tsx          ONNX inference (Offscreen Document — needs DOM)
├── popup/
│   ├── index.tsx              Popup root — sliding panel navigation
│   └── components/
│       ├── MainMenuView.tsx   Main menu + Favourite Prompts section
│       ├── 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
├── ui/memory-panel/
│   └── FloatingMemoryPanel.tsx Draggable floating panel (logo + panel)
├── i18n/
│   ├── translations.ts        8-language string map
│   ├── LanguageContext.tsx    Language switching (localStorage)
│   └── ThemeContext.tsx       Dark / light theme (localStorage)
└── 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

v0.0.4 — 2026-03-06

  • New: Grok (grok.com) support — conversations are silently captured while you browse.
  • New: Gemini passive message capture — existing conversations on the page are automatically captured when you visit.

v0.0.3 — 2026-03-02

  • Perplexity (perplexity.ai) support — conversations are silently captured while you browse. Note: Perplexity itself does not support user data export, so each conversation must be visited individually to be collected.

v0.0.2 — 2026-03-01

  • Full Claude web support (claude.ai) — conversation capture, Recall button injection, and floating memory panel now work on Claude

v0.0.1 — Initial Release 2026-02-24

  • ChatGPT and Gemini conversation capture
  • Hybrid vector + BM25 search with RRF fusion
  • One-click Recall button (ChatGPT, Gemini)
  • Favourite Prompts with Trie autocomplete and drag-and-drop folders
  • Export / import JSON backup
  • Floating memory panel
  • 8 UI languages, dark / light theme

Contributing

PRs and issues are welcome! Please open an issue to discuss significant changes before submitting a PR.


License

Apache 2.0

About

A local-first Chrome extension that passively captures ChatGPT, Gemini, Claude, Grok, Perplexity conversations into a private memory graph. Features in-browser Hybrid RAG (Vector + BM25), semantic search, and 100% privacy via WebAssembly and IndexedDB. No servers, no API keys.

Topics

Resources

License

Stars

Watchers

Forks

Packages