This commit is contained in:
Timothy Jaeryang Baek 2025-04-14 01:08:16 -07:00
parent 403295600f
commit ec3b8fab5b
4 changed files with 69 additions and 49 deletions

View File

@ -339,16 +339,17 @@ def get_event_emitter(request_info, update_db=True):
request_info["message_id"], request_info["message_id"],
) )
content = message.get("content", "") if message:
content += event_data.get("data", {}).get("content", "") content = message.get("content", "")
content += event_data.get("data", {}).get("content", "")
Chats.upsert_message_to_chat_by_id_and_message_id( Chats.upsert_message_to_chat_by_id_and_message_id(
request_info["chat_id"], request_info["chat_id"],
request_info["message_id"], request_info["message_id"],
{ {
"content": content, "content": content,
}, },
) )
if "type" in event_data and event_data["type"] == "replace": if "type" in event_data and event_data["type"] == "replace":
content = event_data.get("data", {}).get("content", "") content = event_data.get("data", {}).get("content", "")

View File

@ -537,8 +537,15 @@ async def chat_image_generation_handler(
for image in images: for image in images:
await __event_emitter__( await __event_emitter__(
{ {
"type": "message", "type": "files",
"data": {"content": f"![Generated Image]({image['url']})\n"}, "data": {
"files": [
{
"type": "image",
"url": image["url"],
}
]
},
} }
) )

View File

@ -262,6 +262,21 @@
} else { } else {
message.statusHistory = [data]; message.statusHistory = [data];
} }
} else if (type === 'chat:completion') {
chatCompletionEventHandler(data, message, event.chat_id);
} else if (type === 'chat:message:delta' || type === 'message') {
message.content += data.content;
} else if (type === 'chat:message' || type === 'replace') {
message.content = data.content;
} else if (type === 'chat:message:files' || type === 'files') {
message.files = data.files;
} else if (type === 'chat:title') {
chatTitle.set(data);
currentChatPage.set(1);
await chats.set(await getChatList(localStorage.token, $currentChatPage));
} else if (type === 'chat:tags') {
chat = await getChatById(localStorage.token, $chatId);
allTags.set(await getAllTags(localStorage.token));
} else if (type === 'source' || type === 'citation') { } else if (type === 'source' || type === 'citation') {
if (data?.type === 'code_execution') { if (data?.type === 'code_execution') {
// Code execution; update existing code execution by ID, or add new one. // Code execution; update existing code execution by ID, or add new one.
@ -288,19 +303,19 @@
message.sources = [data]; message.sources = [data];
} }
} }
} else if (type === 'chat:completion') { } else if (type === 'notification') {
chatCompletionEventHandler(data, message, event.chat_id); const toastType = data?.type ?? 'info';
} else if (type === 'chat:title') { const toastContent = data?.content ?? '';
chatTitle.set(data);
currentChatPage.set(1); if (toastType === 'success') {
await chats.set(await getChatList(localStorage.token, $currentChatPage)); toast.success(toastContent);
} else if (type === 'chat:tags') { } else if (toastType === 'error') {
chat = await getChatById(localStorage.token, $chatId); toast.error(toastContent);
allTags.set(await getAllTags(localStorage.token)); } else if (toastType === 'warning') {
} else if (type === 'chat:message:delta' || type === 'message') { toast.warning(toastContent);
message.content += data.content; } else {
} else if (type === 'chat:message' || type === 'replace') { toast.info(toastContent);
message.content = data.content; }
} else if (type === 'confirmation') { } else if (type === 'confirmation') {
eventCallback = cb; eventCallback = cb;
@ -333,19 +348,6 @@
eventConfirmationMessage = data.message; eventConfirmationMessage = data.message;
eventConfirmationInputPlaceholder = data.placeholder; eventConfirmationInputPlaceholder = data.placeholder;
eventConfirmationInputValue = data?.value ?? ''; eventConfirmationInputValue = data?.value ?? '';
} else if (type === 'notification') {
const toastType = data?.type ?? 'info';
const toastContent = data?.content ?? '';
if (toastType === 'success') {
toast.success(toastContent);
} else if (toastType === 'error') {
toast.error(toastContent);
} else if (toastType === 'warning') {
toast.warning(toastContent);
} else {
toast.info(toastContent);
}
} else { } else {
console.log('Unknown message type', data); console.log('Unknown message type', data);
} }

View File

@ -47,6 +47,7 @@
import CodeExecutions from './CodeExecutions.svelte'; import CodeExecutions from './CodeExecutions.svelte';
import ContentRenderer from './ContentRenderer.svelte'; import ContentRenderer from './ContentRenderer.svelte';
import { KokoroWorker } from '$lib/workers/KokoroWorker'; import { KokoroWorker } from '$lib/workers/KokoroWorker';
import FileItem from '$lib/components/common/FileItem.svelte';
interface MessageType { interface MessageType {
id: string; id: string;
@ -613,18 +614,6 @@
</Name> </Name>
<div> <div>
{#if message?.files && message.files?.filter((f) => f.type === 'image').length > 0}
<div class="my-2.5 w-full flex overflow-x-auto gap-2 flex-wrap">
{#each message.files as file}
<div>
{#if file.type === 'image'}
<Image src={file.url} alt={message.content} />
{/if}
</div>
{/each}
</div>
{/if}
<div class="chat-{message.role} w-full min-w-full markdown-prose"> <div class="chat-{message.role} w-full min-w-full markdown-prose">
<div> <div>
{#if (message?.statusHistory ?? [...(message?.status ? [message?.status] : [])]).length > 0} {#if (message?.statusHistory ?? [...(message?.status ? [message?.status] : [])]).length > 0}
@ -703,6 +692,27 @@
{/if} {/if}
{/if} {/if}
{#if message?.files && message.files?.filter((f) => f.type === 'image').length > 0}
<div class="my-1 w-full flex overflow-x-auto gap-2 flex-wrap">
{#each message.files as file}
<div>
{#if file.type === 'image'}
<Image src={file.url} alt={message.content} />
{:else}
<FileItem
item={file}
url={file.url}
name={file.name}
type={file.type}
size={file?.size}
colorClassName="bg-white dark:bg-gray-850 "
/>
{/if}
</div>
{/each}
</div>
{/if}
{#if edit === true} {#if edit === true}
<div class="w-full bg-gray-50 dark:bg-gray-800 rounded-3xl px-5 py-3 my-2"> <div class="w-full bg-gray-50 dark:bg-gray-800 rounded-3xl px-5 py-3 my-2">
<textarea <textarea