diff --git a/src/lib/components/chat/Messages/MultiResponseMessages.svelte b/src/lib/components/chat/Messages/MultiResponseMessages.svelte
index 3b3dd9b194..c2c6e9fd1e 100644
--- a/src/lib/components/chat/Messages/MultiResponseMessages.svelte
+++ b/src/lib/components/chat/Messages/MultiResponseMessages.svelte
@@ -3,7 +3,7 @@
import { onMount, tick, getContext } from 'svelte';
import { createEventDispatcher } from 'svelte';
- import { mobile, settings } from '$lib/stores';
+ import { mobile, models, settings } from '$lib/stores';
import { generateMoACompletion } from '$lib/apis';
import { updateChatById } from '$lib/apis/chats';
@@ -17,6 +17,8 @@
import Name from './Name.svelte';
import Skeleton from './Skeleton.svelte';
import localizedFormat from 'dayjs/plugin/localizedFormat';
+ import ProfileImage from './ProfileImage.svelte';
+ import { WEBUI_BASE_URL } from '$lib/constants';
const i18n = getContext('i18n');
dayjs.extend(localizedFormat);
@@ -53,6 +55,8 @@
let groupedMessageIds = {};
let groupedMessageIdsIdx = {};
+ let selectedModelIdx = null;
+
let message = JSON.parse(JSON.stringify(history.messages[messageId]));
$: if (history.messages) {
if (JSON.stringify(message) !== JSON.stringify(history.messages[messageId])) {
@@ -183,11 +187,30 @@
}
}, {});
+ selectedModelIdx = history.messages[messageId]?.modelIdx;
+
console.log(groupedMessageIds, groupedMessageIdsIdx);
await tick();
};
+ const onGroupClick = async (_messageId, modelIdx) => {
+ if (messageId != _messageId) {
+ let currentMessageId = _messageId;
+ let messageChildrenIds = history.messages[currentMessageId].childrenIds;
+ while (messageChildrenIds.length !== 0) {
+ currentMessageId = messageChildrenIds.at(-1);
+ messageChildrenIds = history.messages[currentMessageId].childrenIds;
+ }
+ history.currentId = currentMessageId;
+ selectedModelIdx = modelIdx;
+
+ // await tick();
+ // await updateChat();
+ // triggerScroll();
+ }
+ };
+
const mergeResponsesHandler = async () => {
const responses = Object.keys(groupedMessageIds).map((modelIdx) => {
const { messageIds } = groupedMessageIds[modelIdx];
@@ -217,37 +240,58 @@
class="flex snap-x snap-mandatory overflow-x-auto scrollbar-hidden"
id="responses-container-{chatId}-{parentMessage.id}"
>
- {#each Object.keys(groupedMessageIds) as modelIdx}
- {#if groupedMessageIdsIdx[modelIdx] !== undefined && groupedMessageIds[modelIdx].messageIds.length > 0}
-
-
- {@const _messageId =
- groupedMessageIds[modelIdx].messageIds[groupedMessageIdsIdx[modelIdx]]}
+ {#if $settings?.displayMultiModelResponsesInTabs ?? false}
+
+
+
+ {#each Object.keys(groupedMessageIds) as modelIdx}
+ {#if groupedMessageIdsIdx[modelIdx] !== undefined && groupedMessageIds[modelIdx].messageIds.length > 0}
+
+
-
{
- if (messageId != _messageId) {
- let currentMessageId = _messageId;
- let messageChildrenIds = history.messages[currentMessageId].childrenIds;
- while (messageChildrenIds.length !== 0) {
- currentMessageId = messageChildrenIds.at(-1);
- messageChildrenIds = history.messages[currentMessageId].childrenIds;
- }
- history.currentId = currentMessageId;
- // await tick();
- // await updateChat();
- // triggerScroll();
- }
- }}
- >
+ {@const _messageId =
+ groupedMessageIds[modelIdx].messageIds[groupedMessageIdsIdx[modelIdx]]}
+
+ {@const model = $models.find((m) => m.id === history.messages[_messageId]?.model)}
+
+
+ {/if}
+ {/each}
+
+
+
+ {#if selectedModelIdx !== null}
+ {@const _messageId =
+ groupedMessageIds[selectedModelIdx].messageIds[
+ groupedMessageIdsIdx[selectedModelIdx]
+ ]}
{#key history.currentId}
{#if message}
gotoMessage(modelIdx, messageIdx)}
- showPreviousMessage={() => showPreviousMessage(modelIdx)}
- showNextMessage={() => showNextMessage(modelIdx)}
+ siblings={groupedMessageIds[selectedModelIdx].messageIds}
+ gotoMessage={(message, messageIdx) => gotoMessage(selectedModelIdx, messageIdx)}
+ showPreviousMessage={() => showPreviousMessage(selectedModelIdx)}
+ showNextMessage={() => showNextMessage(selectedModelIdx)}
{setInputText}
{updateChat}
{editMessage}
@@ -272,17 +316,73 @@
regenerateResponse={async (message) => {
regenerateResponse(message);
await tick();
- groupedMessageIdsIdx[modelIdx] =
- groupedMessageIds[modelIdx].messageIds.length - 1;
+ groupedMessageIdsIdx[selectedModelIdx] =
+ groupedMessageIds[selectedModelIdx].messageIds.length - 1;
}}
{addMessages}
{readOnly}
/>
{/if}
{/key}
-
- {/if}
- {/each}
+ {/if}
+
+ {:else}
+ {#each Object.keys(groupedMessageIds) as modelIdx}
+ {#if groupedMessageIdsIdx[modelIdx] !== undefined && groupedMessageIds[modelIdx].messageIds.length > 0}
+
+
+ {@const _messageId =
+ groupedMessageIds[modelIdx].messageIds[groupedMessageIdsIdx[modelIdx]]}
+
+ {
+ onGroupClick(_messageId, modelIdx);
+ }}
+ >
+ {#key history.currentId}
+ {#if message}
+ gotoMessage(modelIdx, messageIdx)}
+ showPreviousMessage={() => showPreviousMessage(modelIdx)}
+ showNextMessage={() => showNextMessage(modelIdx)}
+ {setInputText}
+ {updateChat}
+ {editMessage}
+ {saveMessage}
+ {rateMessage}
+ {deleteMessage}
+ {actionMessage}
+ {submitMessage}
+ {continueResponse}
+ regenerateResponse={async (message) => {
+ regenerateResponse(message);
+ await tick();
+ groupedMessageIdsIdx[modelIdx] =
+ groupedMessageIds[modelIdx].messageIds.length - 1;
+ }}
+ {addMessages}
+ {readOnly}
+ />
+ {/if}
+ {/key}
+
+ {/if}
+ {/each}
+ {/if}
{#if !readOnly}
@@ -296,7 +396,7 @@
{#if history.messages[messageId]?.merged?.status}
{@const message = history.messages[messageId]?.merged}
-
+
{$i18n.t('Merged Response')}
diff --git a/src/lib/components/chat/Settings/Interface.svelte b/src/lib/components/chat/Settings/Interface.svelte
index b0c7b89ee6..fb260f7672 100644
--- a/src/lib/components/chat/Settings/Interface.svelte
+++ b/src/lib/components/chat/Settings/Interface.svelte
@@ -36,6 +36,7 @@
let highContrastMode = false;
let detectArtifacts = true;
+ let displayMultiModelResponsesInTabs = false;
let richTextInput = true;
let showFormattingToolbar = false;
@@ -155,6 +156,11 @@
saveSettings({ showEmojiInCall: showEmojiInCall });
};
+ const toggleDisplayMultiModelResponsesInTabs = async () => {
+ displayMultiModelResponsesInTabs = !displayMultiModelResponsesInTabs;
+ saveSettings({ displayMultiModelResponsesInTabs });
+ };
+
const toggleVoiceInterruption = async () => {
voiceInterruption = !voiceInterruption;
saveSettings({ voiceInterruption: voiceInterruption });
@@ -344,6 +350,7 @@
showEmojiInCall = $settings?.showEmojiInCall ?? false;
voiceInterruption = $settings?.voiceInterruption ?? false;
+ displayMultiModelResponsesInTabs = $settings?.displayMultiModelResponsesInTabs ?? false;
chatFadeStreamingText = $settings?.chatFadeStreamingText ?? true;
richTextInput = $settings?.richTextInput ?? true;
@@ -853,6 +860,29 @@
+
+
+
+ {$i18n.t('Display Multi-model Responses in Tabs')}
+
+
+
+
+
+