feat: Persistent AlgoBot chat history with localStorage + clear button (closes #14)#63
feat: Persistent AlgoBot chat history with localStorage + clear button (closes #14)#63arcgod-design wants to merge 2 commits into
Conversation
|
Someone is attempting to deploy a commit to the rishabhjtripathi2903-3434's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthrough
ChangesAlgoBot localStorage Chat Persistence
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ 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.
Actionable comments posted: 2
🤖 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.
Inline comments:
In `@app/src/components/custom/AlgoBot.tsx`:
- Around line 30-34: The saveHistory() flow in AlgoBot is re-persisting an empty
array after “Clear Chat” because it always writes to localStorage even when
there are no conversation messages to save. Update saveHistory(messages) so it
skips setItem when the sliced toStore list is empty (and ideally removes the
STORAGE_KEY instead), keeping the clear action truly empty. Use the existing
saveHistory, STORAGE_KEY, and localStorage call site to make the fix without
affecting normal message persistence.
- Around line 18-23: The restored chat history in loadHistory() is currently
accepted as any non-empty array, which can let malformed items through and cause
renderContent(msg.content) or /api/chat usage to fail. Update loadHistory() in
AlgoBot.tsx to validate each item against the runtime ChatMessage shape before
returning it, drop invalid entries, and cap the recovered list with
slice(-MAX_MESSAGES) so stale oversized history is trimmed on load.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 0644368f-4ecb-4cc8-ad77-c4e1c8aee800
📒 Files selected for processing (1)
app/src/components/custom/AlgoBot.tsx
| function loadHistory(): ChatMessage[] | null { | ||
| try { | ||
| const raw = localStorage.getItem(STORAGE_KEY); | ||
| if (!raw) return null; | ||
| const parsed = JSON.parse(raw); | ||
| if (Array.isArray(parsed) && parsed.length > 0) return parsed; |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Validate and cap restored history before using it.
On Lines 22-23, any non-empty array from localStorage is accepted as ChatMessage[]. A stale/corrupt entry like { content: null } will make renderContent(msg.content) throw on first render, and malformed items also get forwarded to /api/chat. Filter by the runtime ChatMessage shape here and apply slice(-MAX_MESSAGES) on load too.
Suggested fix
function loadHistory(): ChatMessage[] | null {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (!raw) return null;
const parsed = JSON.parse(raw);
- if (Array.isArray(parsed) && parsed.length > 0) return parsed;
- return null;
+ if (!Array.isArray(parsed)) return null;
+
+ const history = parsed
+ .filter(
+ (msg): msg is ChatMessage =>
+ !!msg &&
+ (msg.role === 'user' || msg.role === 'assistant') &&
+ typeof msg.content === 'string'
+ )
+ .slice(-MAX_MESSAGES);
+
+ return history.length > 0 ? history : null;
} catch {
return null;
}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function loadHistory(): ChatMessage[] | null { | |
| try { | |
| const raw = localStorage.getItem(STORAGE_KEY); | |
| if (!raw) return null; | |
| const parsed = JSON.parse(raw); | |
| if (Array.isArray(parsed) && parsed.length > 0) return parsed; | |
| function loadHistory(): ChatMessage[] | null { | |
| try { | |
| const raw = localStorage.getItem(STORAGE_KEY); | |
| if (!raw) return null; | |
| const parsed = JSON.parse(raw); | |
| if (!Array.isArray(parsed)) return null; | |
| const history = parsed | |
| .filter( | |
| (msg): msg is ChatMessage => | |
| !!msg && | |
| (msg.role === 'user' || msg.role === 'assistant') && | |
| typeof msg.content === 'string' | |
| ) | |
| .slice(-MAX_MESSAGES); | |
| return history.length > 0 ? history : null; | |
| } catch { | |
| return null; | |
| } | |
| } |
🤖 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 `@app/src/components/custom/AlgoBot.tsx` around lines 18 - 23, The restored
chat history in loadHistory() is currently accepted as any non-empty array,
which can let malformed items through and cause renderContent(msg.content) or
/api/chat usage to fail. Update loadHistory() in AlgoBot.tsx to validate each
item against the runtime ChatMessage shape before returning it, drop invalid
entries, and cap the recovered list with slice(-MAX_MESSAGES) so stale oversized
history is trimmed on load.
| function saveHistory(messages: ChatMessage[]) { | ||
| try { | ||
| // Skip the welcome message (index 0) — only persist conversation | ||
| const toStore = messages.slice(1).slice(-MAX_MESSAGES); | ||
| localStorage.setItem(STORAGE_KEY, JSON.stringify(toStore)); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Empty history gets written back right after “Clear Chat”.
Because saveHistory() always calls setItem, clearing the chat removes the key and then immediately recreates it as [] when the effect reruns. The UI resets correctly, but the persisted history is not actually cleared.
Suggested fix
function saveHistory(messages: ChatMessage[]) {
try {
// Skip the welcome message (index 0) — only persist conversation
const toStore = messages.slice(1).slice(-MAX_MESSAGES);
- localStorage.setItem(STORAGE_KEY, JSON.stringify(toStore));
+ if (toStore.length === 0) {
+ localStorage.removeItem(STORAGE_KEY);
+ return;
+ }
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(toStore));
} catch {
// Private browsing or quota exceeded — silently ignore
}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function saveHistory(messages: ChatMessage[]) { | |
| try { | |
| // Skip the welcome message (index 0) — only persist conversation | |
| const toStore = messages.slice(1).slice(-MAX_MESSAGES); | |
| localStorage.setItem(STORAGE_KEY, JSON.stringify(toStore)); | |
| function saveHistory(messages: ChatMessage[]) { | |
| try { | |
| // Skip the welcome message (index 0) — only persist conversation | |
| const toStore = messages.slice(1).slice(-MAX_MESSAGES); | |
| if (toStore.length === 0) { | |
| localStorage.removeItem(STORAGE_KEY); | |
| return; | |
| } | |
| localStorage.setItem(STORAGE_KEY, JSON.stringify(toStore)); | |
| } catch { | |
| // Private browsing or quota exceeded — silently ignore | |
| } | |
| } |
🤖 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 `@app/src/components/custom/AlgoBot.tsx` around lines 30 - 34, The
saveHistory() flow in AlgoBot is re-persisting an empty array after “Clear Chat”
because it always writes to localStorage even when there are no conversation
messages to save. Update saveHistory(messages) so it skips setItem when the
sliced toStore list is empty (and ideally removes the STORAGE_KEY instead),
keeping the clear action truly empty. Use the existing saveHistory, STORAGE_KEY,
and localStorage call site to make the fix without affecting normal message
persistence.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Hey @Rishabhworkspace, this PR has been ready for review for a while -- offering this friendly bump. The implementation matches the issue's specified behavior and CI is passing. PR: #63 When you have a moment, a review would be much appreciated. I am happy to iterate on any feedback. If the timing is not right, no worries at all -- just a gentle nudge from a contributor who has been waiting patiently. � |
Related Issue
Closes #14
Description
AlgoBot's chat history now persists across page navigation and browser refresh using localStorage. Messages are capped at 20 to prevent unbounded storage growth. A "Clear Chat" button in the header lets users reset the conversation. localStorage access is wrapped in try/catch for private browsing compatibility.
Type of Change
Screenshots
No visual changes — the Clear Chat button (trash icon) appears in the AlgoBot header only when a conversation has started.
Checklist
Summary by CodeRabbit