Skip to content

Commit

Permalink
Merge pull request #4199 from janhq/fix/4165-refactor-message-builder…
Browse files Browse the repository at this point in the history
…-to-avoid-sending-empty-messages

fix: 4165 - Refactor message builder to avoid sending empty messages
  • Loading branch information
louis-jan authored Dec 3, 2024
2 parents 6244bbd + 7f8517a commit 7f62e84
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 32 deletions.
30 changes: 0 additions & 30 deletions web/hooks/useSendChatMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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'

Expand Down Expand Up @@ -86,33 +84,6 @@ export default function useSendChatMessage() {
selectedModelRef.current = selectedModel
}, [selectedModel])

const normalizeMessages = (
messages: ChatCompletionMessage[]
): ChatCompletionMessage[] => {
const stack = new Stack<ChatCompletionMessage>()
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
Expand Down Expand Up @@ -247,7 +218,6 @@ export default function useSendChatMessage() {
(assistant) => assistant.tools ?? []
) ?? []
)
request.messages = normalizeMessages(request.messages ?? [])

// Request for inference
EngineManager.instance()
Expand Down
33 changes: 31 additions & 2 deletions web/utils/messageRequestBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -36,7 +38,7 @@ export class MessageRequestBuilder {
.filter((e) => e.status !== MessageStatus.Error)
.map<ChatCompletionMessage>((msg) => ({
role: msg.role,
content: msg.content[0]?.text.value ?? '',
content: msg.content[0]?.text.value ?? '.',
}))
}

Expand Down Expand Up @@ -130,12 +132,39 @@ export class MessageRequestBuilder {
return this
}

normalizeMessages = (
messages: ChatCompletionMessage[]
): ChatCompletionMessage[] => {
const stack = new Stack<ChatCompletionMessage>()
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,
}
Expand Down

0 comments on commit 7f62e84

Please sign in to comment.