feat(chat): regenerate variants and support

Hide archived assistant variants in the linear chat view and track
previous assistant as versions so regenerated responses do not
duplicate or lose history. When regenerating, mark the previous assistant
message with an archivedVariant flag for the UI and keep it in server
history. Add a ChatMessageVersion model and a versions field to
ChatMessage to store prior generated variants. Implement
archiveLastAssistantAsVersion in chat providers to snapshot the last
assistant message into versions and reset the message for a fresh
streamed generation. Finalize flow updates to attach an adjacent archived
assistant as a version when needed so the UI can present a switcher
between current and past variants. These changes prevent duplicate
messages, preserve previous responses, and enable variant switching.
This commit is contained in:
cogwheel0
2025-10-23 22:29:28 +05:30
parent 1a38cf02e5
commit 1cb8926e21
5 changed files with 326 additions and 29 deletions

View File

@@ -902,6 +902,13 @@ class _ChatPageState extends ConsumerState<ChatPage> {
}
}
// Hide archived assistant variants in the linear view
final isArchivedVariant =
!isUser && (message.metadata?['archivedVariant'] == true);
if (isArchivedVariant) {
return const SizedBox.shrink();
}
final showFollowUps =
!isUser && !hasUserBubbleBelow && !hasAssistantBubbleBelow;
@@ -990,8 +997,14 @@ class _ChatPageState extends ConsumerState<ChatPage> {
return;
}
// Remove the assistant message we want to regenerate
ref.read(chatMessagesProvider.notifier).removeLastMessage();
// Mark previous assistant as archived for UI; keep it for server history
ref.read(chatMessagesProvider.notifier).updateLastMessageWithFunction((
m,
) {
final meta = Map<String, dynamic>.from(m.metadata ?? const {});
meta['archivedVariant'] = true;
return m.copyWith(metadata: meta, isStreaming: false);
});
// Regenerate response for the previous user message (without duplicating it)
final userMessage = messages[messageIndex - 1];