Studio: Fix empty chat threads on navigation and stabilize new chat flow#4872
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors chat thread initialization to prevent the creation of empty threads by deferring persistence until the first message is sent. Key changes include updating the chat page to check for existing messages before starting a new thread and modifying the sidebar to filter out empty conversations. Feedback highlights a performance issue in the sidebar where observing the messages table causes excessive re-renders during streaming, and suggests using a more efficient existence check when querying the database.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7f9bbe77ca
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| } | ||
|
|
||
| function getInitialSingleChatView(): ChatView { | ||
| const id = useChatRuntimeStore.getState().activeThreadId; |
There was a problem hiding this comment.
Q: Does this work for Side by Side comparison one as well?
There was a problem hiding this comment.
nope, this only restores the initial single-chat view from activeThreadId, compare uses pairId
There was a problem hiding this comment.
hm will disable compare panes from writing global activeThreadId so state won’t bleed across
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e379b519ce
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f97781936e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…er99/unsloth into fix/new-chat-page-switch
…lete flow - Remove __LOCALID_ filter from getInitialSingleChatView: in this Dexie-backed adapter, AUI's __LOCALID_ prefixed IDs ARE the real persistent thread IDs stored by initialize(). Filtering them out breaks thread restoration on navigation. - Simplify handleNewThread to synchronous: the async Dexie message check is redundant (persistence is already deferred to first append) and strands users on legacy empty threads. Use a simple guard that checks the store's activeThreadId to detect unsent drafts. - Add message-count filter to sidebar: filter threads to only show those with at least one message, hiding legacy empty threads. - Add store-based sidebar highlighting fallback: use activeThreadId from the store when view.threadId is not set (nonce-backed chats). - Fix handleDelete to call onNewThread() instead of onSelect(), and clear activeThreadId, so the runtime properly resets after deleting the active thread.
handleDelete was calling onNewThread() after clearing activeThreadId, but the handleNewThread guard sees !view.threadId && !activeThreadId and returns early, leaving the UI stuck on the deleted thread. Fix by directly calling onSelect with a new nonce instead. Restore __LOCALID_ filter in getInitialSingleChatView to prevent restoring unpersisted AUI local thread IDs on navigation. Without this filter, navigating away from /chat before sending a message would restore a non-existent thread that Dexie cannot fetch.
…low (unslothai#4872) * fix(chat): prevent implicit empty thread creation and stabilize new-chat flow * fix(chat): harden compare thread sync and simplify sidebar thread query * fix(chat): harden new-thread state sync and isolate compare active thread updates * fix(chat): stabilize new-thread state sync and prevent compare/session bleed * Fix thread restoration, handleNewThread guard, sidebar filter, and delete flow - Remove __LOCALID_ filter from getInitialSingleChatView: in this Dexie-backed adapter, AUI's __LOCALID_ prefixed IDs ARE the real persistent thread IDs stored by initialize(). Filtering them out breaks thread restoration on navigation. - Simplify handleNewThread to synchronous: the async Dexie message check is redundant (persistence is already deferred to first append) and strands users on legacy empty threads. Use a simple guard that checks the store's activeThreadId to detect unsent drafts. - Add message-count filter to sidebar: filter threads to only show those with at least one message, hiding legacy empty threads. - Add store-based sidebar highlighting fallback: use activeThreadId from the store when view.threadId is not set (nonce-backed chats). - Fix handleDelete to call onNewThread() instead of onSelect(), and clear activeThreadId, so the runtime properly resets after deleting the active thread. * Fix handleDelete nonce path and restore __LOCALID_ filter handleDelete was calling onNewThread() after clearing activeThreadId, but the handleNewThread guard sees !view.threadId && !activeThreadId and returns early, leaving the UI stuck on the deleted thread. Fix by directly calling onSelect with a new nonce instead. Restore __LOCALID_ filter in getInitialSingleChatView to prevent restoring unpersisted AUI local thread IDs on navigation. Without this filter, navigating away from /chat before sending a message would restore a non-existent thread that Dexie cannot fetch. --------- Co-authored-by: Daniel Han <danielhanchen@gmail.com>
…low (unslothai#4872) * fix(chat): prevent implicit empty thread creation and stabilize new-chat flow * fix(chat): harden compare thread sync and simplify sidebar thread query * fix(chat): harden new-thread state sync and isolate compare active thread updates * fix(chat): stabilize new-thread state sync and prevent compare/session bleed * Fix thread restoration, handleNewThread guard, sidebar filter, and delete flow - Remove __LOCALID_ filter from getInitialSingleChatView: in this Dexie-backed adapter, AUI's __LOCALID_ prefixed IDs ARE the real persistent thread IDs stored by initialize(). Filtering them out breaks thread restoration on navigation. - Simplify handleNewThread to synchronous: the async Dexie message check is redundant (persistence is already deferred to first append) and strands users on legacy empty threads. Use a simple guard that checks the store's activeThreadId to detect unsent drafts. - Add message-count filter to sidebar: filter threads to only show those with at least one message, hiding legacy empty threads. - Add store-based sidebar highlighting fallback: use activeThreadId from the store when view.threadId is not set (nonce-backed chats). - Fix handleDelete to call onNewThread() instead of onSelect(), and clear activeThreadId, so the runtime properly resets after deleting the active thread. * Fix handleDelete nonce path and restore __LOCALID_ filter handleDelete was calling onNewThread() after clearing activeThreadId, but the handleNewThread guard sees !view.threadId && !activeThreadId and returns early, leaving the UI stuck on the deleted thread. Fix by directly calling onSelect with a new nonce instead. Restore __LOCALID_ filter in getInitialSingleChatView to prevent restoring unpersisted AUI local thread IDs on navigation. Without this filter, navigating away from /chat before sending a message would restore a non-existent thread that Dexie cannot fetch. --------- Co-authored-by: Daniel Han <danielhanchen@gmail.com>
Switching tabs could create extra empty “New Chat” entries, cluttering the thread list and confusing thread state.
New chat creation now aligns with standard chat UI behaviour: a new conversation is only persisted once the user actually sends a message, not on navigation or empty state transitions.