mirror of
https://github.com/open-webui/open-webui.git
synced 2026-08-28 05:27:35 +00:00
refac
This commit is contained in:
parent
cf887b68ea
commit
73421c5b42
8 changed files with 103 additions and 21 deletions
|
|
@ -920,6 +920,47 @@ export const cloneChatById = async (token: string, id: string, title?: string) =
|
|||
return res;
|
||||
};
|
||||
|
||||
export const forkChatById = async (token: string, id: string, messageId?: string | null) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/fork`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
...(token && { authorization: `Bearer ${token}` })
|
||||
},
|
||||
body: JSON.stringify({
|
||||
message_id: messageId ?? null
|
||||
})
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.then((json) => {
|
||||
return json;
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err;
|
||||
|
||||
if ('detail' in err) {
|
||||
error = err.detail;
|
||||
} else {
|
||||
error = err;
|
||||
}
|
||||
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const cloneSharedChatById = async (token: string, id: string) => {
|
||||
let error = null;
|
||||
|
||||
|
|
|
|||
|
|
@ -70,10 +70,10 @@
|
|||
|
||||
import {
|
||||
archiveChatById,
|
||||
cloneChatById,
|
||||
compactChatById,
|
||||
createNewChat,
|
||||
deleteChatById,
|
||||
forkChatById,
|
||||
getAllTags,
|
||||
getChatById,
|
||||
getTagsById,
|
||||
|
|
@ -1884,6 +1884,9 @@
|
|||
(chatContent?.history ?? undefined) !== undefined
|
||||
? chatContent.history
|
||||
: convertMessagesToHistory(chatContent.messages);
|
||||
if (chat?.current_message_id && history?.messages?.[chat.current_message_id]) {
|
||||
history.currentId = chat.current_message_id;
|
||||
}
|
||||
|
||||
// Sanitize history: repair orphaned references and structurally-malformed
|
||||
// nodes from failed regenerations (#24424, #24157, #20474)
|
||||
|
|
@ -2466,7 +2469,7 @@
|
|||
document.getElementById('chat-input')?.focus();
|
||||
};
|
||||
|
||||
const handleForkChat = async () => {
|
||||
const handleForkChat = async (messageId: string | null = null) => {
|
||||
if (!$chatId || !history?.currentId) {
|
||||
toast.message($i18n.t('No chat to fork'));
|
||||
return;
|
||||
|
|
@ -2489,13 +2492,7 @@
|
|||
const toastId = toast.loading($i18n.t('Forking chat...'));
|
||||
|
||||
try {
|
||||
const result = await cloneChatById(
|
||||
localStorage.token,
|
||||
$chatId,
|
||||
$i18n.t('Clone of {{TITLE}}', {
|
||||
TITLE: $chatTitle || 'Chat'
|
||||
})
|
||||
);
|
||||
const result = await forkChatById(localStorage.token, $chatId, messageId ?? history.currentId);
|
||||
|
||||
if (result?.id) {
|
||||
if (!embedded) {
|
||||
|
|
@ -3725,6 +3722,7 @@
|
|||
{mergeResponses}
|
||||
{chatActionHandler}
|
||||
{addMessages}
|
||||
forkHandler={generating || taskIds?.length ? null : handleForkChat}
|
||||
topPadding={!embedded}
|
||||
bottomPadding={files.length > 0}
|
||||
{onSelect}
|
||||
|
|
|
|||
|
|
@ -183,10 +183,10 @@
|
|||
</button>
|
||||
</Tooltip>
|
||||
{:else if item.data.id === 'fork'}
|
||||
<Tooltip content="Clone this chat into a new copy." placement="top">
|
||||
<Tooltip content="Fork the current chat branch into a new chat." placement="top">
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Fork: clone this chat into a new copy."
|
||||
aria-label="Fork: fork the current chat branch into a new chat."
|
||||
class="slash-command-row flex items-center gap-2 w-full h-6 px-2 rounded-xl text-xs text-left transition-colors duration-75
|
||||
{commandIdx === selectedIdx ? 'app-interactive-active' : ''} disabled:opacity-50"
|
||||
disabled={forkDisabled}
|
||||
|
|
@ -222,7 +222,7 @@
|
|||
</span>
|
||||
<span class="flex-1 min-w-0 flex items-baseline gap-1.5 overflow-hidden">
|
||||
<span class="truncate">Fork</span>
|
||||
<span class="app-muted text-[0.625rem] truncate shrink-0">Clone chat</span>
|
||||
<span class="app-muted text-[0.625rem] truncate shrink-0">Current branch</span>
|
||||
</span>
|
||||
</button>
|
||||
</Tooltip>
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
export let showMessage: Function = () => {};
|
||||
export let submitMessage: Function = () => {};
|
||||
export let addMessages: Function = () => {};
|
||||
export let forkHandler: Function | null = null;
|
||||
|
||||
export let readOnly = false;
|
||||
export let editCodeBlock = true;
|
||||
|
|
@ -539,6 +540,7 @@
|
|||
{continueResponse}
|
||||
{mergeResponses}
|
||||
{addMessages}
|
||||
{forkHandler}
|
||||
{triggerScroll}
|
||||
{readOnly}
|
||||
{editCodeBlock}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
export let mergeResponses;
|
||||
|
||||
export let addMessages;
|
||||
export let forkHandler: Function | null = null;
|
||||
export let triggerScroll;
|
||||
export let readOnly = false;
|
||||
export let editCodeBlock = true;
|
||||
|
|
@ -97,6 +98,7 @@
|
|||
{continueResponse}
|
||||
{regenerateResponse}
|
||||
{addMessages}
|
||||
{forkHandler}
|
||||
{readOnly}
|
||||
{editCodeBlock}
|
||||
{topPadding}
|
||||
|
|
@ -122,6 +124,7 @@
|
|||
{mergeResponses}
|
||||
{triggerScroll}
|
||||
{addMessages}
|
||||
{forkHandler}
|
||||
{readOnly}
|
||||
{editCodeBlock}
|
||||
{topPadding}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
export let mergeResponses: Function;
|
||||
|
||||
export let addMessages: Function;
|
||||
export let forkHandler: Function | null = null;
|
||||
|
||||
export let triggerScroll: Function;
|
||||
|
||||
|
|
@ -319,6 +320,7 @@
|
|||
groupedMessageIds[selectedModelIdx].messageIds.length - 1;
|
||||
}}
|
||||
{addMessages}
|
||||
{forkHandler}
|
||||
{readOnly}
|
||||
{topPadding}
|
||||
{onInsertToNote}
|
||||
|
|
@ -376,6 +378,7 @@
|
|||
groupedMessageIds[modelIdx].messageIds.length - 1;
|
||||
}}
|
||||
{addMessages}
|
||||
{forkHandler}
|
||||
{readOnly}
|
||||
{editCodeBlock}
|
||||
{topPadding}
|
||||
|
|
|
|||
|
|
@ -159,6 +159,7 @@
|
|||
export let submitMessage: Function;
|
||||
export let continueResponse: Function;
|
||||
export let regenerateResponse: Function;
|
||||
export let forkHandler: Function | null = null;
|
||||
|
||||
export let addMessages: Function;
|
||||
|
||||
|
|
@ -1054,6 +1055,37 @@
|
|||
</button>
|
||||
</Tooltip>
|
||||
|
||||
{#if message.done && !readOnly && forkHandler}
|
||||
<Tooltip content="Fork chat" placement="bottom">
|
||||
<button
|
||||
aria-label="Fork chat"
|
||||
class="{isLastMessage || ($settings?.highContrastMode ?? false)
|
||||
? 'visible'
|
||||
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
|
||||
on:click={() => {
|
||||
forkHandler?.(message.id);
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
class="w-4 h-4"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.8"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="M4 12H9" />
|
||||
<path d="M9 12C12.5 12 12.5 7 16 7H20" />
|
||||
<path d="M17 4L20 7L17 10" />
|
||||
<path d="M9 12C12.5 12 12.5 17 16 17H20" />
|
||||
<path d="M17 14L20 17L17 20" />
|
||||
</svg>
|
||||
</button>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
|
||||
{#if onInsertToNote && visibleResponseContent}
|
||||
<Tooltip content={$i18n.t('Insert into note')} placement="bottom">
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -203,25 +203,28 @@ export const convertMessagesToHistory = (messages) => {
|
|||
let messageId = null;
|
||||
|
||||
for (const message of messages) {
|
||||
messageId = uuidv4();
|
||||
|
||||
if (parentMessageId !== null) {
|
||||
history.messages[parentMessageId].childrenIds = [
|
||||
...history.messages[parentMessageId].childrenIds,
|
||||
messageId
|
||||
];
|
||||
}
|
||||
messageId = message?.id ?? uuidv4();
|
||||
const parentId = message?.parentId ?? parentMessageId;
|
||||
|
||||
history.messages[messageId] = {
|
||||
...message,
|
||||
id: messageId,
|
||||
parentId: parentMessageId,
|
||||
parentId,
|
||||
childrenIds: []
|
||||
};
|
||||
|
||||
parentMessageId = messageId;
|
||||
}
|
||||
|
||||
for (const message of Object.values(history.messages)) {
|
||||
if (message.parentId && history.messages[message.parentId]) {
|
||||
history.messages[message.parentId].childrenIds = [
|
||||
...history.messages[message.parentId].childrenIds,
|
||||
message.id
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
history.currentId = messageId;
|
||||
return history;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue