feat: add user memory feature for persisting preferences across conversations #146
feat: add user memory feature for persisting preferences across conversations #146bbsngg merged 5 commits intoOpenLAIR:mainfrom
Conversation
…rsations Add a memory system similar to ChatGPT/Claude/Gemini memory. Users can save preferences, habits, and context via Settings > Memory tab. Enabled memories are injected into system prompts across all providers (Claude SDK, OpenRouter, LocalGPU, Gemini). Includes full CRUD API, global toggle, and per-memory enable/disable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When memories are created/updated/deleted/toggled via the UI, they are now synced to: - ~/.claude/MEMORY.md — standalone file readable by terminal users - ~/.claude/CLAUDE.md — managed section so Claude Code CLI loads memories automatically for all projects Also injects memories into dr-claw chat (cli-chat.js) system prompt by reading ~/.claude/MEMORY.md at startup. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PR Review — @HenryPengZouOverall clean feature with well-structured CRUD. A few issues from security to correctness need attention before merge. 🔴 CRITICAL — Must Fix1. Global 2. 🟠 HIGH — Strongly Recommend Fixing3. 4. Memory content injected without sanitization into system prompts
5. No 6. Delete has no confirmation 🟡 MEDIUM — Suggested Improvements
✅ Looks Good
Verdict: Do not merge as-is. Fix #1 and #2 (critical design issues that will cause bugs with multiple users). #3–#6 are straightforward hardening. The rest are quality improvements. |
…r fixes Fixes for PR OpenLAIR#146 review by @Zhang-Henry: Critical: - OpenLAIR#1: memory_enabled is now per-user (column on users table) instead of global app_settings. Each user controls their own memory toggle. - OpenLAIR#2: ~/.claude/MEMORY.md namespaced as MEMORY-{userId}.md to prevent multi-user overwrites on shared servers. High: - OpenLAIR#3: req.params.id validated as positive integer with parseInt + isNaN guard - OpenLAIR#4: Memory content sanitized (strip markdown headings) before prompt injection; content length capped at 500 chars; max 50 memories per user - OpenLAIR#5: Content length validation (400 error) on create and update routes - OpenLAIR#6: Delete now requires window.confirm() before executing Medium: - OpenLAIR#8: Removed no-op try/catch wrappers from all memoryDb methods - OpenLAIR#9: Added comment explaining why Gemini injects memory into user prompt (CLI has no system instruction API) - OpenLAIR#10: Changed index from (is_enabled) to composite (user_id, is_enabled) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ser conflict
The CLAUDE.md managed section was the last shared resource that could
cause multi-user overwrites. Removed entirely because:
- Option A (web UI) injects memories via buildMemoryBlock() into system
prompts directly from the DB — never reads any file
- The CLAUDE.md section was only needed for Option B (terminal CLI),
which is not the primary use case
What remains:
- ~/.claude/MEMORY-{userId}.md — user-scoped reference file (read-only)
- DB → system prompt injection for all web UI sessions (the main path)
Also removed dead MEMORY.md reading from cli-chat.js since it lacks
user auth context to resolve the user-scoped filename.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Thanks for the thorough review @Zhang-Henry! All critical and high-priority issues are addressed 🔴 CRITICAL1 —
2 — Multi-user file conflict fully resolved
🟠 HIGH3 —
4 — Memory content sanitized against prompt injection
5 — Content length validation on create/update
6 — Delete confirmation added
🟡 MEDIUM8 — Removed no-op
9 — Gemini injection documented
10 — Index fixed
Not addressed (low priority)
|
Both branches added imports and route mounts at the same location in server/index.js. Kept both: memoryRoutes and communityToolsRoutes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
Gemini)
~/.claude/MEMORY.mdfor terminal-only (Option B) users [update: now synced to~/.claude/MEMORY-{userId}.md(user-scoped) to avoid multi-user file conflict, e.g.,~/.claude/MEMORY-1.md]/api/memorywith global enable/disable toggleTest plan
~/.claude/MEMORY-{userId}.mdis synced after changes