mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-19 14:41:24 +08:00
fix: preserve thinking block (#11901)
* fix: preserve thinking block * test: add coverage for reasoning parts in assistant messages (#11902) * Initial plan * test: add test coverage for reasoning parts in assistant messages Co-authored-by: DeJeune <67425183+DeJeune@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: DeJeune <67425183+DeJeune@users.noreply.github.com> --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
parent
a1e44a6827
commit
fd921103dd
@ -109,6 +109,20 @@ const createImageBlock = (
|
|||||||
...overrides
|
...overrides
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const createThinkingBlock = (
|
||||||
|
messageId: string,
|
||||||
|
overrides: Partial<Omit<ThinkingMessageBlock, 'type' | 'messageId'>> = {}
|
||||||
|
): ThinkingMessageBlock => ({
|
||||||
|
id: overrides.id ?? `thinking-block-${++blockCounter}`,
|
||||||
|
messageId,
|
||||||
|
type: MessageBlockType.THINKING,
|
||||||
|
createdAt: overrides.createdAt ?? new Date(2024, 0, 1, 0, 0, blockCounter).toISOString(),
|
||||||
|
status: overrides.status ?? MessageBlockStatus.SUCCESS,
|
||||||
|
content: overrides.content ?? 'Let me think...',
|
||||||
|
thinking_millsec: overrides.thinking_millsec ?? 1000,
|
||||||
|
...overrides
|
||||||
|
})
|
||||||
|
|
||||||
describe('messageConverter', () => {
|
describe('messageConverter', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
convertFileBlockToFilePartMock.mockReset()
|
convertFileBlockToFilePartMock.mockReset()
|
||||||
@ -229,6 +243,23 @@ describe('messageConverter', () => {
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('includes reasoning parts for assistant messages with thinking blocks', async () => {
|
||||||
|
const model = createModel()
|
||||||
|
const message = createMessage('assistant')
|
||||||
|
message.__mockContent = 'Here is my answer'
|
||||||
|
message.__mockThinkingBlocks = [createThinkingBlock(message.id, { content: 'Let me think...' })]
|
||||||
|
|
||||||
|
const result = await convertMessageToSdkParam(message, false, model)
|
||||||
|
|
||||||
|
expect(result).toEqual({
|
||||||
|
role: 'assistant',
|
||||||
|
content: [
|
||||||
|
{ type: 'text', text: 'Here is my answer' },
|
||||||
|
{ type: 'reasoning', text: 'Let me think...' }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('convertMessagesToSdkMessages', () => {
|
describe('convertMessagesToSdkMessages', () => {
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
* 将 Cherry Studio 消息格式转换为 AI SDK 消息格式
|
* 将 Cherry Studio 消息格式转换为 AI SDK 消息格式
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type { ReasoningPart } from '@ai-sdk/provider-utils'
|
||||||
import { loggerService } from '@logger'
|
import { loggerService } from '@logger'
|
||||||
import { isImageEnhancementModel, isVisionModel } from '@renderer/config/models'
|
import { isImageEnhancementModel, isVisionModel } from '@renderer/config/models'
|
||||||
import type { Message, Model } from '@renderer/types'
|
import type { Message, Model } from '@renderer/types'
|
||||||
@ -163,13 +164,13 @@ async function convertMessageToAssistantModelMessage(
|
|||||||
thinkingBlocks: ThinkingMessageBlock[],
|
thinkingBlocks: ThinkingMessageBlock[],
|
||||||
model?: Model
|
model?: Model
|
||||||
): Promise<AssistantModelMessage> {
|
): Promise<AssistantModelMessage> {
|
||||||
const parts: Array<TextPart | FilePart> = []
|
const parts: Array<TextPart | ReasoningPart | FilePart> = []
|
||||||
if (content) {
|
if (content) {
|
||||||
parts.push({ type: 'text', text: content })
|
parts.push({ type: 'text', text: content })
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const thinkingBlock of thinkingBlocks) {
|
for (const thinkingBlock of thinkingBlocks) {
|
||||||
parts.push({ type: 'text', text: thinkingBlock.content })
|
parts.push({ type: 'reasoning', text: thinkingBlock.content })
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const fileBlock of fileBlocks) {
|
for (const fileBlock of fileBlocks) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user