feat: configurable chat history scrollback#423
feat: configurable chat history scrollback#423amanthanvi wants to merge 11 commits intoDimillian:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements configurable chat history scrollback to prevent losing older messages in long-running threads. The implementation adds an app-wide setting (default 200 items) that can be increased up to 5000 or set to unlimited, and uses virtualization to maintain UI performance with large histories.
Changes:
- Adds
chatHistoryScrollbackItemssetting (number | null) to control thread item retention per thread - Implements virtualization for the Messages component using @tanstack/react-virtual with ResizeObserver
- Provides Settings UI with unlimited toggle, preset selector (200/500/1000/2000/5000), and custom number input
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/utils/threadItems.ts | Adds optional maxItemsPerThread parameter to prepareThreadItems with null for unlimited |
| src/utils/threadItems.test.ts | Tests custom and unlimited scrollback limits |
| src/types.ts | Adds chatHistoryScrollbackItems: number | null to AppSettings type |
| src/features/threads/hooks/useThreadsReducer.ts | Adds maxItemsPerThread to ThreadState and setMaxItemsPerThread action |
| src/features/threads/hooks/useThreadsReducer.test.ts | Tests trimming when maxItemsPerThread is reduced |
| src/features/threads/hooks/useThreads.ts | Plumbs chatHistoryScrollbackItems setting into reducer via useEffect |
| src/features/threads/hooks/threadReducer/threadItemsSlice.ts | Passes maxItemsPerThread option to all prepareThreadItems calls |
| src/features/threads/hooks/threadReducer/threadConfigSlice.ts | New slice to handle setMaxItemsPerThread action and re-process all threads |
| src/features/settings/hooks/useAppSettings.ts | Adds normalization for chatHistoryScrollbackItems (clamps 50-5000, rounds) |
| src/features/settings/components/sections/SettingsDisplaySection.tsx | Implements Chat scrollback UI with toggle, presets, and input |
| src/features/settings/components/sections/SettingsDisplaySection.test.tsx | Tests unlimited toggle and preset selection |
| src/features/messages/components/Messages.tsx | Replaces flat rendering with virtualized list using useVirtualizer and ResizeObserver |
| src/features/messages/components/Messages.test.tsx | Mocks useVirtualizer for tests |
| src/styles/messages.css | Adds CSS for virtual list container and rows |
| src-tauri/src/types.rs | Adds chat_history_scrollback_items: Option<u32> to Rust AppSettings with default 200 |
| src/App.tsx | Passes chatHistoryScrollbackItems to useThreads hook |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba45a268d7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7b9fb1301c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Follow-ups pushed to address review feedback:
CI is green (lint/typecheck/test + Rust + Tauri builds). |
|
@codex review |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const observer = new ResizeObserver(() => { | ||
| rowVirtualizerRef.current.measureElement(node); | ||
| requestAutoScrollRef.current(); | ||
| }); |
There was a problem hiding this comment.
Superfluous argument passed to default constructor of class ResizeObserverMock.
|
Codex Review: Didn't find any major issues. Bravo. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@amanthanvi it introduces an issue, when loading an old thread, and trying to scrollup it'll jump back to the bottom making it almost impossible to scroll up |
|
Overall lot of complexity by virtualizing the conversation view |
|
Got it. Hoping a nice way to add this can be figured out somewhere down the line. Appreciate you taking a look at it! @Dimillian |
|
Follow-up: opened #427 as a reduced-scope alternative (same configurable scrollback setting + retention logic, but no Messages virtualization) based on the scroll-jump + complexity feedback here. |
Fixes #422
What
@tanstack/react-virtual).Notes
How to validate
Tests
npm run lintnpm run typechecknpm run testcd src-tauri && cargo test