diff --git a/extensions/inference-nitro-extension/bin/version.txt b/extensions/inference-nitro-extension/bin/version.txt index 5f749c136..75274d832 100644 --- a/extensions/inference-nitro-extension/bin/version.txt +++ b/extensions/inference-nitro-extension/bin/version.txt @@ -1 +1 @@ -0.4.11 +0.4.12 diff --git a/web/hooks/useSendChatMessage.ts b/web/hooks/useSendChatMessage.ts index 59282aa9f..8c6013505 100644 --- a/web/hooks/useSendChatMessage.ts +++ b/web/hooks/useSendChatMessage.ts @@ -10,6 +10,7 @@ import { ConversationalExtension, EngineManager, ToolManager, + ChatCompletionMessage, } from '@janhq/core' import { atom, useAtom, useAtomValue, useSetAtom } from 'jotai' @@ -19,6 +20,7 @@ import { fileUploadAtom, } from '@/containers/Providers/Jotai' +import { Stack } from '@/utils/Stack' import { compressImage, getBase64 } from '@/utils/base64' import { MessageRequestBuilder } from '@/utils/messageRequestBuilder' import { toRuntimeParams, toSettingParams } from '@/utils/modelParam' @@ -90,6 +92,33 @@ 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) => { if (!activeThreadRef.current) { console.error('No active thread') @@ -140,6 +169,8 @@ export default function useSendChatMessage() { ) ?? [] ) + request.messages = normalizeMessages(request.messages ?? []) + const engine = requestBuilder.model?.engine ?? selectedModelRef.current?.engine ?? '' @@ -258,6 +289,7 @@ export default function useSendChatMessage() { (assistant) => assistant.tools ?? [] ) ?? [] ) + request.messages = normalizeMessages(request.messages ?? []) // Request for inference EngineManager.instance() diff --git a/web/utils/Stack.ts b/web/utils/Stack.ts new file mode 100644 index 000000000..277b2859b --- /dev/null +++ b/web/utils/Stack.ts @@ -0,0 +1,31 @@ +export class Stack { + private array: T[] = [] + + pop(): T | undefined { + if (this.isEmpty()) throw new Error() + + return this.array.pop() + } + + push(data: T): void { + this.array.push(data) + } + + peek(): T { + if (this.isEmpty()) throw new Error() + + return this.array[this.array.length - 1] + } + + isEmpty(): boolean { + return this.array.length === 0 + } + + size(): number { + return this.array.length + } + + reverseOutput(): T[] { + return [...this.array] + } +}