From c021aba094cec2d00b846763e4a7906da050cce7 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Tue, 28 Jan 2025 12:49:06 -0800 Subject: [PATCH] enh: chat "clone" i18n --- backend/open_webui/routers/chats.py | 10 ++++++++-- src/lib/apis/chats/index.ts | 7 +++++-- src/lib/components/layout/Sidebar/ChatItem.svelte | 8 +++++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/backend/open_webui/routers/chats.py b/backend/open_webui/routers/chats.py index a001dd01f..2efd043ef 100644 --- a/backend/open_webui/routers/chats.py +++ b/backend/open_webui/routers/chats.py @@ -444,15 +444,21 @@ async def pin_chat_by_id(id: str, user=Depends(get_verified_user)): ############################ +class CloneForm(BaseModel): + title: Optional[str] = None + + @router.post("/{id}/clone", response_model=Optional[ChatResponse]) -async def clone_chat_by_id(id: str, user=Depends(get_verified_user)): +async def clone_chat_by_id( + form_data: CloneForm, id: str, user=Depends(get_verified_user) +): chat = Chats.get_chat_by_id_and_user_id(id, user.id) if chat: updated_chat = { **chat.chat, "originalChatId": chat.id, "branchPointMessageId": chat.chat["history"]["currentId"], - "title": f"Clone of {chat.title}", + "title": form_data.title if form_data.title else f"Clone of {chat.title}", } chat = Chats.insert_new_chat(user.id, ChatForm(**{"chat": updated_chat})) diff --git a/src/lib/apis/chats/index.ts b/src/lib/apis/chats/index.ts index 1772529d3..7af504cc7 100644 --- a/src/lib/apis/chats/index.ts +++ b/src/lib/apis/chats/index.ts @@ -580,7 +580,7 @@ export const toggleChatPinnedStatusById = async (token: string, id: string) => { return res; }; -export const cloneChatById = async (token: string, id: string) => { +export const cloneChatById = async (token: string, id: string, title?: string) => { let error = null; const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/clone`, { @@ -589,7 +589,10 @@ export const cloneChatById = async (token: string, id: string) => { Accept: 'application/json', 'Content-Type': 'application/json', ...(token && { authorization: `Bearer ${token}` }) - } + }, + body: JSON.stringify({ + ...(title && { title: title }) + }) }) .then(async (res) => { if (!res.ok) throw await res.json(); diff --git a/src/lib/components/layout/Sidebar/ChatItem.svelte b/src/lib/components/layout/Sidebar/ChatItem.svelte index 748e1adb9..1e9224093 100644 --- a/src/lib/components/layout/Sidebar/ChatItem.svelte +++ b/src/lib/components/layout/Sidebar/ChatItem.svelte @@ -87,7 +87,13 @@ }; const cloneChatHandler = async (id) => { - const res = await cloneChatById(localStorage.token, id).catch((error) => { + const res = await cloneChatById( + localStorage.token, + id, + $i18n.t('Clone of {{TITLE}}', { + TITLE: title + }) + ).catch((error) => { toast.error(`${error}`); return null; });