-
Notifications
You must be signed in to change notification settings - Fork 51
Daily branch 2025 11 20 #109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
433192f
d08dee1
80aba28
03c96f6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -298,9 +298,17 @@ export const useChatHandlers = ({ | |
| : todos; | ||
| if (cleanedTodos !== todos) setTodos(cleanedTodos); | ||
|
|
||
| // Check if the last assistant message has actual content | ||
| // If it's empty or has no parts, it was never saved (error occurred) | ||
| // In this case, we shouldn't delete anything from the database | ||
| const hasContent = lastAssistant?.parts && lastAssistant.parts.length > 0; | ||
|
|
||
| if (!temporaryChatsEnabled) { | ||
| // Delete last assistant message and update todos in a single transaction | ||
| await deleteLastAssistantMessage({ chatId, todos: cleanedTodos }); | ||
| // Only delete if the last assistant message has content | ||
| // This prevents deleting previous valid messages when an error occurred | ||
| if (hasContent) { | ||
| await deleteLastAssistantMessage({ chatId, todos: cleanedTodos }); | ||
| } | ||
| // For persisted chats, backend fetches from database - explicitly send no messages | ||
| regenerate({ | ||
| body: { | ||
|
|
@@ -348,11 +356,21 @@ export const useChatHandlers = ({ | |
| }, | ||
| }); | ||
| } else { | ||
| // For temporary chats, send all messages | ||
| // For temporary chats, filter out empty assistant message if present (from error) | ||
| // Check if last message is an empty assistant message | ||
| const lastMessage = messages[messages.length - 1]; | ||
| const isLastMessageEmptyAssistant = | ||
| lastMessage?.role === "assistant" && | ||
| (!lastMessage.parts || lastMessage.parts.length === 0); | ||
|
|
||
| const messagesToSend = isLastMessageEmptyAssistant | ||
| ? messages.slice(0, -1) | ||
| : messages; | ||
|
|
||
| regenerate({ | ||
| body: { | ||
| mode: chatMode, | ||
| messages, | ||
| messages: messagesToSend, | ||
|
Comment on lines
+359
to
+373
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Good implementation for temporary chats, but consider persisted chats consistency. The filtering logic for empty assistant messages in temporary chats is well-implemented with clear variable naming and proper conditional handling. However, there's an inconsistency: persisted chats (lines 347-357) don't handle empty assistant messages at all. If an empty assistant message exists in the database (due to the issue flagged above), the backend will fetch it during retry, while temporary chats would filter it out. This creates divergent behavior between the two modes. For consistency, consider deleting empty assistant messages in persisted chats as well: if (!temporaryChatsEnabled) {
+ // Check if last message is an empty assistant message from an error
+ const lastMessage = messages[messages.length - 1];
+ const isLastMessageEmptyAssistant =
+ lastMessage?.role === "assistant" &&
+ (!lastMessage.parts || lastMessage.parts.length === 0);
+
+ // Delete empty assistant message if present
+ if (isLastMessageEmptyAssistant) {
+ await deleteLastAssistantMessage({ chatId, todos: cleanedTodos });
+ }
+
// For persisted chats, backend fetches from database - explicitly send no messages
regenerate({
🤖 Prompt for AI Agents |
||
| todos: cleanedTodos, | ||
| regenerate: true, | ||
| temporary: true, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential bug: Empty assistant messages may still be saved to the database.
The guard assumes that if
hasContentis false, the message was never saved to the database. However,handleStop(lines 266-276) callssaveAssistantMessagewithout checking whetherpartsis empty. This means an empty assistant message can be saved if an error occurs immediately after the stream starts.When regenerating, if the empty message exists in the database but
hasContentis false in the UI state, the deletion will be skipped. The backend will then fetch the empty assistant message from the database, which could cause incorrect regeneration context.Consider one of these approaches:
Option 1: Always attempt deletion (simplest)
Option 2: Prevent saving empty messages in handleStop
Modify
handleStopto checklastMessage.parts?.length > 0before callingsaveAssistantMessage.Option 3: Delete when lastAssistant exists (regardless of content)
if (!temporaryChatsEnabled) { - // Only delete if the last assistant message has content - // This prevents deleting previous valid messages when an error occurred - if (hasContent) { + // Delete the last assistant message if one exists in the UI state + // This includes empty messages that may have been saved during errors + if (lastAssistant) { await deleteLastAssistantMessage({ chatId, todos: cleanedTodos }); }📝 Committable suggestion
🤖 Prompt for AI Agents