Skip to content

Conversation

@peppescg
Copy link
Collaborator

@peppescg peppescg commented Dec 23, 2025

Chat History with Dexie.js

Kapture.2025-12-23.at.17.26.01.mp4

Overview

Implemented conversation history persistence for the assistant using Dexie.js as an IndexedDB wrapper. Conversations are automatically saved in the browser and can be restored, searched, deleted and managed by the user.

Database Structure

Database name: ToolHiveCloudUIChatDB

Tables:

  • conversations: stores conversation metadata (id, title, model, createdAt, updatedAt)
  • messages: stores messages (id, conversationId, role, content, parts, metadata, createdAt)

Features

  1. Auto-save: Messages are automatically saved with 500ms debounce
  2. Auto-restore: The last conversation is loaded on open
  3. Conversation list: Accessible by clicking "Assistant" in the header
  4. Search: Filter conversations by title or model
  5. New conversation: Button to start a fresh chat
  6. Delete: Each conversation can be deleted with confirmation
  7. Auto-title: Generated from the user's first message

UI

  • Popover triggered by "Assistant" + ChevronDown icon in header
  • ScrollArea for conversation list
  • Search input at the top
  • Each item displays: title, relative time, delete button
  • "Clear Chat" button with secondary variant (dark background by default)

Moved the assistant chat to the right side of the application

- Install Dexie.js for IndexedDB management
- Create database schema in features/assistant/db/
- Define StoredConversation and StoredMessage types
- Implement basic CRUD operations for conversations and messages
- Filter out system messages when saving (only user/assistant visible)
- Create useChatHistory hook for conversation management
- Auto-save messages to IndexedDB with debouncing (500ms)
- Save conversation metadata (model, selectedServers)
- Generate conversation title from first user message
- Export useChatHistory from assistant feature index
- Load most recent conversation when ChatProvider mounts
- Restore selected model from conversation metadata
- Only load if no messages are already present
- Export useChatHistory hook from assistant feature
- Start new conversation instead of clearing current one
- Ensures clearMessages() properly resets conversation state
- Required for React hooks (useEffect) in Next.js App Router
- Fixes build error for client-side hook
- More descriptive name matching project structure
- Expose isLoadingHistory from ChatContext
- Show centered Loader2 spinner in ChatInterface (line 54)
- Hide empty state and messages while loading
- IndexedDB loads too fast for spinner to be visible
- Removed isLoadingHistory from ChatContext and ChatInterface
- Keeps code simpler without unnecessary loading state
- Expose conversations and management functions from ChatContext
- Create ConversationList component with search functionality
- Add popover in ChatHeader with chevron indicator
- Support selecting, deleting, and creating conversations
- Include date-fns for relative time formatting
- Fix hydration error: use sibling buttons instead of nested buttons
- Add margin to ChevronDown for better spacing from 'Assistant'
- Fix 'New conversation' not clearing messages by preventing auto-reload after initial mount
- Center garbage icon vertically with items-center
- Improve delete button styling with hover states
- Add space-y-1 to prevent delete icon overlap on hover
- Use secondary variant for dark background by default
- Add overflow-hidden to conversation item containers
- Properly constrain text to allow truncation
- Add isLoadingConversationRef to skip auto-save on load
- Prevents updatedAt from being updated when viewing old conversations
- Conversations now stay sorted by actual last message time
- Replace native button elements with Button component
- Use ghost variant for conversation items
- Use icon size for delete button
- Replace h-4 w-4 with size-4
- Replace h-6 w-6 with size-6
- Replace native button with Button component
- Use ghost variant for consistent styling
- Replace custom button elements with Button from @/components/ui/button
- Update image-modal.tsx close button to use Button variant='ghost'
- Update reasoning.tsx toggle button to use Button component
- Update tool-call.tsx toggle buttons to use Button component
- Remove redundant comment in sidebar.tsx
@peppescg peppescg self-assigned this Dec 23, 2025
Copilot AI review requested due to automatic review settings December 23, 2025 15:50
@github-actions github-actions bot added the size/L Large PR: 600-999 lines changed label Dec 23, 2025
@github-actions github-actions bot added size/L Large PR: 600-999 lines changed and removed size/L Large PR: 600-999 lines changed labels Dec 23, 2025
@peppescg peppescg changed the title feat(assistant): add dexie db leveraging browser IndexedDB feat(assistant): add dexie db leveraging browser indexed db Dec 23, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements conversation history persistence for the assistant using Dexie.js as an IndexedDB wrapper, enabling browser-based chat history storage and management. The implementation includes auto-save with debouncing, auto-restore of the last conversation, and a full conversation management UI.

Key changes:

  • Database layer with Dexie.js for storing conversations and messages in IndexedDB
  • Auto-save mechanism with 500ms debounce to persist chat messages
  • Conversation list UI with search, delete, and selection capabilities accessible via popover
  • Assistant sidebar moved from left to right side of the application

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/features/assistant/db/database.ts Defines Dexie database schema with conversations and messages tables
src/features/assistant/db/types.ts TypeScript interfaces for StoredConversation and StoredMessage
src/features/assistant/db/storage.ts Database operations for CRUD on conversations and messages
src/features/assistant/db/index.ts Barrel export for database module
src/features/assistant/hooks/use-chat-history.ts Custom hook managing chat history state and database interactions
src/features/assistant/contexts/chat-context.tsx Integration of chat history with auto-save and auto-restore logic
src/features/assistant/components/sidebar.tsx Changed sidebar position from left to right
src/features/assistant/components/sidebar-content.tsx Added conversation management props to ChatInterface
src/components/chat/conversation-list.tsx New component for displaying and managing conversation list
src/components/chat/chat-interface.tsx Added conversation management props
src/components/chat/chat-header.tsx Added popover trigger for conversation list and changed button variant
src/components/ui/popover.tsx New shadcn/ui popover component
src/components/navbar.tsx Reorganized navbar layout moving logo and assistant trigger
package.json Added dexie and @radix-ui/react-popover dependencies
pnpm-lock.yaml Lock file updates for new dependencies
src/features/assistant/index.ts Exported useChatHistory hook
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

- Create useChatTransport hook for transport creation with refs pattern
- Create useChatPersistence hook for auto-load and auto-save logic
- Simplify ChatProvider from 238 to 97 lines
- Improve separation of concerns and testability
- Use getConversation(id) instead of getAllConversations().find()
- Extract extractTitleFromMessages helper function
- ChatInterface now uses useChatContext directly
- Simplify sidebar-content from 50 to 11 lines
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/L Large PR: 600-999 lines changed labels Dec 23, 2025
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Large PR Detected

This PR exceeds 1000 lines of changes and requires justification before it can be reviewed.

How to unblock this PR:

Add a section to your PR description with the following format:

## Large PR Justification

[Explain why this PR must be large, such as:]

- Generated code that cannot be split
- Large refactoring that must be atomic
- Multiple related changes that would break if separated
- Migration or data transformation

Alternative:

Consider splitting this PR into smaller, focused changes (< 1000 lines each) for easier review and reduced risk.

See our Contributing Guidelines for more details on the pull request process.


This review will be automatically dismissed once you add the justification section.

- Replace delete-all + insert-all pattern with upsert
- Reduces I/O operations by ~50% for large conversations
- bulkPut inserts new messages and updates existing ones
- Save only when streaming completes (status: streaming -> ready)
- Remove setTimeout/debounce pattern
- Reduce from 129 to 97 lines
- Cleaner state tracking with previousStatusRef
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Dec 23, 2025
- Remove async from clearMessages to avoid unhandled promise
- Use .catch() for error handling instead of await
- UI clears immediately, conversation creation happens in background
- Move 'New Conversation' button from dropdown to header
- Remove 'Clear Chat' button and related confirmation dialog
- Remove 'New conversation' option from conversation list dropdown
- Simplify ChatHeader and ConversationList props
- Fix duplicate hover text color warning
- Add deleteAllConversations function to storage layer
- Add clearAll method to useChatHistory hook
- Add clearAllConversations to ChatContext
- Add 'Clear all messages' button to conversation list dropdown
- Includes confirmation dialog before clearing
- Replace ErrorAlert component with toast notification for chat errors
- Disable 'New Conversation' button when chat is empty
- Remove unused ErrorAlert import and component
- Simplify ConversationItem to use native buttons
- Remove conflicting hover states from nested Button components
- Show delete icon only on hover with smooth transition
- Fix visual overlap issues in dropdown
- Add overflow-hidden to container to prevent content overflow
- Replace ScrollArea with native overflow-y-auto for simpler layout
- Always show delete icon (remove hover-only visibility)
- Reduce max-height to max-h-64 for better containment
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Dec 23, 2025
@peppescg peppescg dismissed github-actions[bot]’s stale review December 23, 2025 16:27

the refactor reduce the number of lines

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Large PR Detected

This PR exceeds 1000 lines of changes and requires justification before it can be reviewed.

How to unblock this PR:

Add a section to your PR description with the following format:

## Large PR Justification

[Explain why this PR must be large, such as:]

- Generated code that cannot be split
- Large refactoring that must be atomic
- Multiple related changes that would break if separated
- Migration or data transformation

Alternative:

Consider splitting this PR into smaller, focused changes (< 1000 lines each) for easier review and reduced risk.

See our Contributing Guidelines for more details on the pull request process.


This review will be automatically dismissed once you add the justification section.

@peppescg peppescg merged commit 1a5ae79 into main Dec 23, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XL Extra large PR: 1000+ lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants