From 7f8517afc53f595f0cc3a757c0712dcbaed4ce01 Mon Sep 17 00:00:00 2001 From: Louis Date: Tue, 3 Dec 2024 15:16:48 +0700 Subject: [PATCH] fix: 4165 - Refactor message builder to avoid sending empty messages --- web/hooks/useSendChatMessage.ts | 30 --------------------------- web/utils/messageRequestBuilder.ts | 33 ++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/web/hooks/useSendChatMessage.ts b/web/hooks/useSendChatMessage.ts index 815bdf116a..dc9a52f1be 100644 --- a/web/hooks/useSendChatMessage.ts +++ b/web/hooks/useSendChatMessage.ts @@ -10,7 +10,6 @@ import { ConversationalExtension, EngineManager, ToolManager, - ChatCompletionMessage, } from '@janhq/core' import { extractInferenceParams, extractModelLoadParams } from '@janhq/core' import { atom, useAtom, useAtomValue, useSetAtom } from 'jotai' @@ -21,7 +20,6 @@ import { fileUploadAtom, } from '@/containers/Providers/Jotai' -import { Stack } from '@/utils/Stack' import { compressImage, getBase64 } from '@/utils/base64' import { MessageRequestBuilder } from '@/utils/messageRequestBuilder' @@ -86,33 +84,6 @@ export default function useSendChatMessage() { selectedModelRef.current = selectedModel }, [selectedModel]) - const normalizeMessages = ( - messages: ChatCompletionMessage[] - ): ChatCompletionMessage[] => { - const stack = new Stack() - for (const message of messages) { - if (stack.isEmpty()) { - stack.push(message) - continue - } - const topMessage = stack.peek() - - if (message.role === topMessage.role) { - // add an empty message - stack.push({ - role: - topMessage.role === ChatCompletionRole.User - ? ChatCompletionRole.Assistant - : ChatCompletionRole.User, - content: '.', // some model requires not empty message - }) - } - stack.push(message) - } - - return stack.reverseOutput() - } - const resendChatMessage = async (currentMessage: ThreadMessage) => { // Delete last response before regenerating const newConvoData = currentMessages @@ -247,7 +218,6 @@ export default function useSendChatMessage() { (assistant) => assistant.tools ?? [] ) ?? [] ) - request.messages = normalizeMessages(request.messages ?? []) // Request for inference EngineManager.instance() diff --git a/web/utils/messageRequestBuilder.ts b/web/utils/messageRequestBuilder.ts index 949b4405ca..3153a7e3eb 100644 --- a/web/utils/messageRequestBuilder.ts +++ b/web/utils/messageRequestBuilder.ts @@ -15,6 +15,8 @@ import { ulid } from 'ulidx' import { FileType } from '@/containers/Providers/Jotai' +import { Stack } from '@/utils/Stack' + export class MessageRequestBuilder { msgId: string type: MessageRequestType @@ -36,7 +38,7 @@ export class MessageRequestBuilder { .filter((e) => e.status !== MessageStatus.Error) .map((msg) => ({ role: msg.role, - content: msg.content[0]?.text.value ?? '', + content: msg.content[0]?.text.value ?? '.', })) } @@ -130,12 +132,39 @@ export class MessageRequestBuilder { return this } + normalizeMessages = ( + messages: ChatCompletionMessage[] + ): ChatCompletionMessage[] => { + const stack = new Stack() + for (const message of messages) { + if (stack.isEmpty()) { + stack.push(message) + continue + } + const topMessage = stack.peek() + + if (message.role === topMessage.role) { + // add an empty message + stack.push({ + role: + topMessage.role === ChatCompletionRole.User + ? ChatCompletionRole.Assistant + : ChatCompletionRole.User, + content: '.', // some model requires not empty message + }) + } + stack.push(message) + } + + return stack.reverseOutput() + } + build(): MessageRequest { return { id: this.msgId, type: this.type, threadId: this.thread.id, - messages: this.messages, + messages: this.normalizeMessages(this.messages), model: this.model, thread: this.thread, }