refactor: unify message model handling across components

- Replaced direct usage of modelId with model object in Message, MessageHeader, MessageMenubar, and TranslatePage components for consistency.
- Introduced getMessageModelId utility function to streamline model retrieval from messages.
- Updated event handling in Messages component to align with new model structure.
- Enhanced code readability and maintainability by reducing redundancy in model handling.
This commit is contained in:
kangfenmao 2025-01-22 13:29:21 +08:00
parent 4d201059ad
commit a566b0e91a
9 changed files with 20 additions and 16 deletions

View File

@ -5,6 +5,7 @@ import { useModel } from '@renderer/hooks/useModel'
import { useMessageStyle, useSettings } from '@renderer/hooks/useSettings'
import { fetchChatCompletion } from '@renderer/services/ApiService'
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
import { getMessageModelId } from '@renderer/services/MessagesService'
import { estimateMessageUsage } from '@renderer/services/TokenService'
import { Message, Topic } from '@renderer/types'
import { classNames, runAsyncFunction } from '@renderer/utils'
@ -52,7 +53,7 @@ const MessageItem: FC<Props> = ({
const [message, setMessage] = useState(_message)
const { t } = useTranslation()
const { assistant, setModel } = useAssistant(message.assistantId)
const model = useModel(message.modelId)
const model = useModel(getMessageModelId(message))
const { isBubbleStyle } = useMessageStyle()
const { showMessageDivider, messageFont, fontSize } = useSettings()
const messageContainerRef = useRef<HTMLDivElement>(null)
@ -165,7 +166,7 @@ const MessageItem: FC<Props> = ({
})}
ref={messageContainerRef}
style={{ ...style, alignItems: isBubbleStyle ? (isAssistantMessage ? 'start' : 'end') : undefined }}>
<MessageHeader message={message} assistant={assistant} model={model} key={message.modelId} />
<MessageHeader message={message} assistant={assistant} model={model} key={getMessageModelId(message)} />
<MessageContentContainer
className="message-content-container"
style={{ fontFamily, fontSize, background: messageBackground }}>

View File

@ -5,6 +5,7 @@ import { getModelLogo } from '@renderer/config/models'
import { useTheme } from '@renderer/context/ThemeProvider'
import useAvatar from '@renderer/hooks/useAvatar'
import { useMessageStyle, useSettings } from '@renderer/hooks/useSettings'
import { getMessageModelId } from '@renderer/services/MessagesService'
import { Assistant, Message, Model } from '@renderer/types'
import { firstLetter, removeLeadingEmoji } from '@renderer/utils'
import { Avatar } from 'antd'
@ -31,7 +32,7 @@ const MessageHeader: FC<Props> = memo(({ assistant, model, message }) => {
const { t } = useTranslation()
const { isBubbleStyle } = useMessageStyle()
const avatarSource = useMemo(() => getAvatarSource(isLocalAi, message.modelId), [message.modelId])
const avatarSource = useMemo(() => getAvatarSource(isLocalAi, getMessageModelId(message)), [message])
const getUserName = useCallback(() => {
if (isLocalAi && message.role !== 'user') return APP_NAME

View File

@ -84,7 +84,7 @@ const MessageMenubar: FC<Props> = (props) => {
...nextMessage,
content: '',
status: 'sending',
modelId: assistantModel?.id || model?.id,
model: assistantModel || model,
translatedContent: undefined
})
}
@ -93,7 +93,7 @@ const MessageMenubar: FC<Props> = (props) => {
EventEmitter.emit(EVENT_NAMES.SEND_MESSAGE, { ...message, id: uuid() })
onDeleteMessage?.(message)
}
}, [assistantModel?.id, message, model?.id, onDeleteMessage, onGetMessages])
}, [assistantModel, message, model, onDeleteMessage, onGetMessages])
const onEdit = useCallback(async () => {
let resendMessage = false
@ -169,7 +169,7 @@ const MessageMenubar: FC<Props> = (props) => {
[message, onEdit, onNewBranch, t]
)
const onDeleteAndRegenerate = async () => {
const onRegenerate = async () => {
await modelGenerating()
const selectedModel = await SelectModelPopup.show({ model })
if (!selectedModel) return
@ -180,7 +180,6 @@ const MessageMenubar: FC<Props> = (props) => {
reasoning_content: undefined,
metrics: undefined,
status: 'sending',
modelId: selectedModel.id,
model: selectedModel,
translatedContent: undefined,
metadata: undefined
@ -214,7 +213,7 @@ const MessageMenubar: FC<Props> = (props) => {
</Tooltip>
{isAssistantMessage && (
<Tooltip title={t('common.regenerate')} mouseEnterDelay={0.8}>
<ActionButton className="message-action-button" onClick={onDeleteAndRegenerate}>
<ActionButton className="message-action-button" onClick={onRegenerate}>
<SyncOutlined />
</ActionButton>
</Tooltip>

View File

@ -164,8 +164,7 @@ const Messages: FC<Props> = ({ assistant, topic, setActiveTopic }) => {
}),
EventEmitter.on(EVENT_NAMES.REGENERATE_MESSAGE, async (model: Model) => {
const lastUserMessage = last(filterMessages(messages).filter((m) => m.role === 'user'))
lastUserMessage &&
onSendMessage({ ...lastUserMessage, id: uuid(), modelId: model.id, model: model, mentions: [model] })
lastUserMessage && onSendMessage({ ...lastUserMessage, id: uuid(), model: model, mentions: [model] })
}),
EventEmitter.on(EVENT_NAMES.AI_AUTO_RENAME, autoRenameTopic),
EventEmitter.on(EVENT_NAMES.CLEAR_MESSAGES, () => {

View File

@ -55,7 +55,7 @@ const TranslatePage: FC = () => {
content: text,
assistantId: assistant.id,
topicId: uuid(),
modelId: translateModel.id,
model: translateModel,
createdAt: new Date().toISOString(),
type: 'text',
status: 'sending'

View File

@ -133,7 +133,7 @@ export async function addAssistantMessagesToTopic({ assistant, topic }: { assist
topicId: topic.id,
createdAt: new Date().toISOString(),
status: 'success',
modelId: assistant.defaultModel?.id || defaultModel.id,
model: assistant.defaultModel || defaultModel,
type: 'text',
isPreset: true
}

View File

@ -86,7 +86,7 @@ export function getUserMessage({
content: content || '',
assistantId: assistant.id,
topicId: topic.id,
modelId: model.id,
model,
createdAt: new Date().toISOString(),
type,
status: 'success'
@ -104,7 +104,6 @@ export function getAssistantMessage({ assistant, topic }: { assistant: Assistant
assistantId: assistant.id,
topicId: topic.id,
model,
modelId: model.id,
createdAt: new Date().toISOString(),
type: 'text',
status: 'sending'
@ -150,3 +149,7 @@ export function getGroupedMessages(messages: Message[]): { [key: string]: (Messa
})
return groups
}
export function getMessageModelId(message: Message) {
return message?.model?.id || message.modelId
}

View File

@ -5,6 +5,7 @@ import MessageContent from '@renderer/pages/home/Messages/MessageContent'
import MessageErrorBoundary from '@renderer/pages/home/Messages/MessageErrorBoundary'
import { fetchChatCompletion } from '@renderer/services/ApiService'
import { getDefaultAssistant, getDefaultModel } from '@renderer/services/AssistantService'
import { getMessageModelId } from '@renderer/services/MessagesService'
import { Message } from '@renderer/types'
import { isMiniWindow } from '@renderer/utils'
import { Dispatch, FC, memo, SetStateAction, useEffect, useMemo, useRef, useState } from 'react'
@ -24,7 +25,7 @@ const getMessageBackground = (isBubbleStyle: boolean, isAssistantMessage: boolea
const MessageItem: FC<Props> = ({ message: _message, index, total, route, onSetMessages, onGetMessages }) => {
const [message, setMessage] = useState(_message)
const model = useModel(message.modelId)
const model = useModel(getMessageModelId(message))
const isBubbleStyle = true
const { messageFont, fontSize } = useSettings()
const messageContainerRef = useRef<HTMLDivElement>(null)

View File

@ -45,7 +45,7 @@ const Translate: FC<Props> = ({ text }) => {
content: text,
assistantId: assistant.id,
topicId: uuid(),
modelId: translateModel.id,
model: translateModel,
createdAt: new Date().toISOString(),
type: 'text',
status: 'sending'