feat: persist AI chat history to localStorage across page refreshes#307
feat: persist AI chat history to localStorage across page refreshes#307KaparthyReddy wants to merge 3 commits into
Conversation
- Add CHAT_HISTORY key to STORAGE_KEYS in lib/constants/config.ts - Add loadChatHistory() to load persisted messages on store init - Update addMessage() to save chat history to localStorage on every message - Update clearChat() to remove chat history from localStorage on clear - Follows the same localStorage persistence pattern used for API keys, editor theme, and inline suggestions in the same store
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
👋 Thanks for opening a PR, @KaparthyReddy!Your PR has entered the 🚦 PR Review Pipeline.
What happens next
A pipeline status comment will appear below and update automatically as your PR progresses. While you wait
This comment is posted only once. |
|
Warning Review limit reached
More reviews will be available in 15 minutes and 32 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
WalkthroughAdds a ChangesChat History Persistence
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
modules/playground/hooks/useAI.ts (1)
94-104: ⚡ Quick winConsider adding a size limit to prevent localStorage quota issues.
Chat history grows unbounded over time. Unlike API keys or theme settings (which are fixed-size), the chatMessages array will continuously grow with usage. This could eventually exceed localStorage quota limits (typically 5-10MB), causing persistence to silently fail.
♻️ Limit chat history to last N messages
const updated = [...s.chatMessages, newMessage]; - try { localStorage.setItem(STORAGE_KEYS.CHAT_HISTORY, JSON.stringify(updated)); } catch { } + const toStore = updated.slice(-100); // Keep last 100 messages + try { localStorage.setItem(STORAGE_KEYS.CHAT_HISTORY, JSON.stringify(toStore)); } catch { } return { chatMessages: updated };This keeps the in-memory state complete while limiting persisted history to prevent quota issues.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@modules/playground/hooks/useAI.ts` around lines 94 - 104, The addMessage setter in useAI.ts currently persists the entire chatMessages array to localStorage (STORAGE_KEYS.CHAT_HISTORY) which can grow without bound; modify addMessage so it still appends newMessage to the in-memory s.chatMessages but only writes a bounded tail (e.g., last N entries, configurable constant like MAX_PERSISTED_MESSAGES) to localStorage—compute persistedArray = updated.slice(-MAX_PERSISTED_MESSAGES) before JSON.stringify, keep the try/catch around localStorage.setItem, and document/centralize MAX_PERSISTED_MESSAGES near the hook so persistence quota is protected while in-memory state remains complete.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@modules/playground/hooks/useAI.ts`:
- Around line 94-104: The addMessage setter in useAI.ts currently persists the
entire chatMessages array to localStorage (STORAGE_KEYS.CHAT_HISTORY) which can
grow without bound; modify addMessage so it still appends newMessage to the
in-memory s.chatMessages but only writes a bounded tail (e.g., last N entries,
configurable constant like MAX_PERSISTED_MESSAGES) to localStorage—compute
persistedArray = updated.slice(-MAX_PERSISTED_MESSAGES) before JSON.stringify,
keep the try/catch around localStorage.setItem, and document/centralize
MAX_PERSISTED_MESSAGES near the hook so persistence quota is protected while
in-memory state remains complete.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: e398d11e-0d63-4787-8ae9-95e3da913be0
📒 Files selected for processing (2)
lib/constants/config.tsmodules/playground/hooks/useAI.ts
…alStorage quota issues
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
modules/playground/hooks/useAI.ts (1)
62-70:⚠️ Potential issue | 🟠 Major | ⚡ Quick winValidate and cap chat history on load to avoid runtime crashes.
loadChatHistory()currently trusts parsed JSON asChatMessage[]. IflocalStoragecontains non-array JSON, lateraddMessagecan fail when spreadings.chatMessages. Also, read-side capping should match the new write cap.Proposed fix
function loadChatHistory(): ChatMessage[] { if (typeof window === "undefined") return []; try { const stored = localStorage.getItem(STORAGE_KEYS.CHAT_HISTORY); - return stored ? (JSON.parse(stored) as ChatMessage[]) : []; + if (!stored) return []; + const parsed: unknown = JSON.parse(stored); + if (!Array.isArray(parsed)) return []; + return (parsed as ChatMessage[]).slice(-MAX_PERSISTED_MESSAGES); } catch { return []; } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@modules/playground/hooks/useAI.ts` around lines 62 - 70, loadChatHistory currently trusts parsed localStorage JSON as ChatMessage[] which can crash later when addMessage spreads s.chatMessages; modify loadChatHistory to validate the parsed value is an array of objects (and optionally validate minimal ChatMessage shape), fall back to [] on malformed data, and trim the returned array to MAX_PERSISTED_MESSAGES so read-side capping matches the write cap; reference the STORAGE_KEYS.CHAT_HISTORY key, the loadChatHistory function, and MAX_PERSISTED_MESSAGES constant when implementing these checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@modules/playground/hooks/useAI.ts`:
- Around line 62-70: loadChatHistory currently trusts parsed localStorage JSON
as ChatMessage[] which can crash later when addMessage spreads s.chatMessages;
modify loadChatHistory to validate the parsed value is an array of objects (and
optionally validate minimal ChatMessage shape), fall back to [] on malformed
data, and trim the returned array to MAX_PERSISTED_MESSAGES so read-side capping
matches the write cap; reference the STORAGE_KEYS.CHAT_HISTORY key, the
loadChatHistory function, and MAX_PERSISTED_MESSAGES constant when implementing
these checks.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: eccf4639-66b2-4e8a-8e67-3c2456824a8f
📒 Files selected for processing (1)
modules/playground/hooks/useAI.ts
Summary
CHAT_HISTORYkey toSTORAGE_KEYSinlib/constants/config.tsloadChatHistory()to load persisted messages on store initializationaddMessage()to save chat history to localStorage on every new messageclearChat()to remove chat history from localStorage on clearPreviously,
chatMessageswas always initialized to[], meaning every page refresh wiped the entire AI conversation. This change ensures chat history survives refreshes and tab closes.Type of change
Related issue
Closes #265
Validation
npm run lintnpm testnpm run buildManual verification performed:
Screenshots or recordings
No UI changes — this is a pure localStorage persistence fix in the Zustand store.
Checklist
Summary by CodeRabbit