fix(MessageMenubar): handle assistant messages from reasoning models when copying and editing content

This commit is contained in:
ousugo 2025-03-21 14:51:42 +08:00 committed by 亢奋猫
parent 27a384b0c8
commit 55bb4530c0

View File

@ -16,6 +16,7 @@ import ObsidianExportPopup from '@renderer/components/Popups/ObsidianExportPopup
import SelectModelPopup from '@renderer/components/Popups/SelectModelPopup' import SelectModelPopup from '@renderer/components/Popups/SelectModelPopup'
import TextEditPopup from '@renderer/components/Popups/TextEditPopup' import TextEditPopup from '@renderer/components/Popups/TextEditPopup'
import { TranslateLanguageOptions } from '@renderer/config/translate' import { TranslateLanguageOptions } from '@renderer/config/translate'
import { isReasoningModel } from '@renderer/config/models'
import { useMessageOperations } from '@renderer/hooks/useMessageOperations' import { useMessageOperations } from '@renderer/hooks/useMessageOperations'
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService' import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
import { getMessageTitle, resetAssistantMessage } from '@renderer/services/MessagesService' import { getMessageTitle, resetAssistantMessage } from '@renderer/services/MessagesService'
@ -23,6 +24,7 @@ import { translateText } from '@renderer/services/TranslateService'
import { Message, Model } from '@renderer/types' import { Message, Model } from '@renderer/types'
import { Assistant, Topic } from '@renderer/types' import { Assistant, Topic } from '@renderer/types'
import { captureScrollableDivAsBlob, captureScrollableDivAsDataURL, removeTrailingDoubleSpaces } from '@renderer/utils' import { captureScrollableDivAsBlob, captureScrollableDivAsDataURL, removeTrailingDoubleSpaces } from '@renderer/utils'
import { withMessageThought } from '@renderer/utils/formats'
import { import {
exportMarkdownToJoplin, exportMarkdownToJoplin,
exportMarkdownToNotion, exportMarkdownToNotion,
@ -35,6 +37,8 @@ import dayjs from 'dayjs'
import { FC, memo, useCallback, useMemo, useState } from 'react' import { FC, memo, useCallback, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
import { clone } from 'lodash'
interface Props { interface Props {
message: Message message: Message
assistant: Assistant assistant: Assistant
@ -72,12 +76,21 @@ const MessageMenubar: FC<Props> = (props) => {
const onCopy = useCallback( const onCopy = useCallback(
(e: React.MouseEvent) => { (e: React.MouseEvent) => {
e.stopPropagation() e.stopPropagation()
// 只处理助手消息和来自推理模型的消息
if (message.role === 'assistant' && message.model && isReasoningModel(message.model)) {
const processedMessage = withMessageThought(clone(message))
navigator.clipboard.writeText(removeTrailingDoubleSpaces(processedMessage.content.trimStart()))
} else {
// 其他情况直接复制原始内容
navigator.clipboard.writeText(removeTrailingDoubleSpaces(message.content.trimStart())) navigator.clipboard.writeText(removeTrailingDoubleSpaces(message.content.trimStart()))
}
window.message.success({ content: t('message.copied'), key: 'copy-message' }) window.message.success({ content: t('message.copied'), key: 'copy-message' })
setCopied(true) setCopied(true)
setTimeout(() => setCopied(false), 2000) setTimeout(() => setCopied(false), 2000)
}, },
[message.content, t] [message, t]
) )
const onNewBranch = useCallback(async () => { const onNewBranch = useCallback(async () => {
@ -98,8 +111,15 @@ const MessageMenubar: FC<Props> = (props) => {
const onEdit = useCallback(async () => { const onEdit = useCallback(async () => {
let resendMessage = false let resendMessage = false
let textToEdit = message.content
if (message.role === 'assistant' && message.model && isReasoningModel(message.model)) {
const processedMessage = withMessageThought(clone(message))
textToEdit = processedMessage.content
}
const editedText = await TextEditPopup.show({ const editedText = await TextEditPopup.show({
text: message.content, text: textToEdit,
children: (props) => { children: (props) => {
const onPress = () => { const onPress = () => {
props.onOk?.() props.onOk?.()
@ -115,7 +135,7 @@ const MessageMenubar: FC<Props> = (props) => {
} }
}) })
if (editedText && editedText !== message.content) { if (editedText && editedText !== textToEdit) {
await editMessage(message.id, { content: editedText }) await editMessage(message.id, { content: editedText })
resendMessage && handleResendUserMessage({ ...message, content: editedText }) resendMessage && handleResendUserMessage({ ...message, content: editedText })
} }