mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-19 06:30:10 +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
|
||||
})
|
||||
|
||||
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', () => {
|
||||
beforeEach(() => {
|
||||
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', () => {
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
* 将 Cherry Studio 消息格式转换为 AI SDK 消息格式
|
||||
*/
|
||||
|
||||
import type { ReasoningPart } from '@ai-sdk/provider-utils'
|
||||
import { loggerService } from '@logger'
|
||||
import { isImageEnhancementModel, isVisionModel } from '@renderer/config/models'
|
||||
import type { Message, Model } from '@renderer/types'
|
||||
@ -163,13 +164,13 @@ async function convertMessageToAssistantModelMessage(
|
||||
thinkingBlocks: ThinkingMessageBlock[],
|
||||
model?: Model
|
||||
): Promise<AssistantModelMessage> {
|
||||
const parts: Array<TextPart | FilePart> = []
|
||||
const parts: Array<TextPart | ReasoningPart | FilePart> = []
|
||||
if (content) {
|
||||
parts.push({ type: 'text', text: content })
|
||||
}
|
||||
|
||||
for (const thinkingBlock of thinkingBlocks) {
|
||||
parts.push({ type: 'text', text: thinkingBlock.content })
|
||||
parts.push({ type: 'reasoning', text: thinkingBlock.content })
|
||||
}
|
||||
|
||||
for (const fileBlock of fileBlocks) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user