mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-09 14:59:27 +08:00
fix/magistral-2507
This commit is contained in:
parent
bf30bf28a9
commit
aa635eba88
@ -270,7 +270,7 @@
|
|||||||
"winston-daily-rotate-file": "^5.0.0",
|
"winston-daily-rotate-file": "^5.0.0",
|
||||||
"word-extractor": "^1.0.4",
|
"word-extractor": "^1.0.4",
|
||||||
"zipread": "^1.3.3",
|
"zipread": "^1.3.3",
|
||||||
"zod": "^3.25.74"
|
"zod": "^4.0.0"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"pdf-parse@npm:1.1.1": "patch:pdf-parse@npm%3A1.1.1#~/.yarn/patches/pdf-parse-npm-1.1.1-04a6109b2a.patch",
|
"pdf-parse@npm:1.1.1": "patch:pdf-parse@npm%3A1.1.1#~/.yarn/patches/pdf-parse-npm-1.1.1-04a6109b2a.patch",
|
||||||
|
|||||||
@ -52,6 +52,7 @@ import {
|
|||||||
import { ChunkType, TextStartChunk, ThinkingStartChunk } from '@renderer/types/chunk'
|
import { ChunkType, TextStartChunk, ThinkingStartChunk } from '@renderer/types/chunk'
|
||||||
import { Message } from '@renderer/types/newMessage'
|
import { Message } from '@renderer/types/newMessage'
|
||||||
import {
|
import {
|
||||||
|
MistralDeltaSchema,
|
||||||
OpenAISdkMessageParam,
|
OpenAISdkMessageParam,
|
||||||
OpenAISdkParams,
|
OpenAISdkParams,
|
||||||
OpenAISdkRawChunk,
|
OpenAISdkRawChunk,
|
||||||
@ -804,7 +805,8 @@ export class OpenAIAPIClient extends OpenAIBaseClient<
|
|||||||
(typeof choice.delta.content === 'string' && choice.delta.content !== '') ||
|
(typeof choice.delta.content === 'string' && choice.delta.content !== '') ||
|
||||||
(typeof (choice.delta as any).reasoning_content === 'string' &&
|
(typeof (choice.delta as any).reasoning_content === 'string' &&
|
||||||
(choice.delta as any).reasoning_content !== '') ||
|
(choice.delta as any).reasoning_content !== '') ||
|
||||||
(typeof (choice.delta as any).reasoning === 'string' && (choice.delta as any).reasoning !== ''))
|
(typeof (choice.delta as any).reasoning === 'string' && (choice.delta as any).reasoning !== '') ||
|
||||||
|
Array.isArray(choice.delta.content))
|
||||||
) {
|
) {
|
||||||
contentSource = choice.delta
|
contentSource = choice.delta
|
||||||
} else if ('message' in choice) {
|
} else if ('message' in choice) {
|
||||||
@ -815,8 +817,15 @@ export class OpenAIAPIClient extends OpenAIBaseClient<
|
|||||||
if (!contentSource?.content) {
|
if (!contentSource?.content) {
|
||||||
accumulatingText = false
|
accumulatingText = false
|
||||||
}
|
}
|
||||||
// @ts-ignore - reasoning_content is not in standard OpenAI types but some providers use it
|
const mistralDelta = MistralDeltaSchema.safeParse(contentSource?.content)
|
||||||
if (!contentSource?.reasoning_content && !contentSource?.reasoning) {
|
|
||||||
|
if (
|
||||||
|
// @ts-ignore - reasoning_content is not in standard OpenAI types but some providers use it
|
||||||
|
!contentSource?.reasoning_content &&
|
||||||
|
// @ts-ignore - reasoning is not in standard OpenAI types but some providers use it
|
||||||
|
!contentSource?.reasoning &&
|
||||||
|
(mistralDelta.data?.[0]?.type !== 'thinking' || !mistralDelta.success)
|
||||||
|
) {
|
||||||
isThinking = false
|
isThinking = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -850,12 +859,14 @@ export class OpenAIAPIClient extends OpenAIBaseClient<
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理推理内容 (e.g. from OpenRouter DeepSeek-R1)
|
// 处理推理内容 (e.g. from OpenRouter DeepSeek-R1)
|
||||||
// @ts-ignore - reasoning_content is not in standard OpenAI types but some providers use it
|
const reasoningText =
|
||||||
const reasoningText = contentSource.reasoning_content || contentSource.reasoning
|
// @ts-ignore - reasoning_content is not in standard OpenAI types but some providers use it
|
||||||
|
contentSource.reasoning_content ||
|
||||||
|
// @ts-ignore - reasoning_content is not in standard OpenAI types but some providers use it
|
||||||
|
contentSource.reasoning ||
|
||||||
|
(mistralDelta.data?.[0]?.type === 'thinking' ? mistralDelta.data?.[0]?.thinking[0]?.text : undefined)
|
||||||
if (reasoningText) {
|
if (reasoningText) {
|
||||||
// logger.silly('since reasoningText is trusy, try to enqueue THINKING_START AND THINKING_DELTA')
|
|
||||||
if (!isThinking) {
|
if (!isThinking) {
|
||||||
// logger.silly('since isThinking is falsy, try to enqueue THINKING_START')
|
|
||||||
controller.enqueue({
|
controller.enqueue({
|
||||||
type: ChunkType.THINKING_START
|
type: ChunkType.THINKING_START
|
||||||
} as ThinkingStartChunk)
|
} as ThinkingStartChunk)
|
||||||
@ -872,22 +883,35 @@ export class OpenAIAPIClient extends OpenAIBaseClient<
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理文本内容
|
// 处理文本内容
|
||||||
if (contentSource.content) {
|
if (mistralDelta.success && mistralDelta.data?.[0]?.type === 'text') {
|
||||||
// logger.silly('since contentSource.content is trusy, try to enqueue TEXT_START and TEXT_DELTA')
|
|
||||||
if (!accumulatingText) {
|
if (!accumulatingText) {
|
||||||
// logger.silly('enqueue TEXT_START')
|
|
||||||
controller.enqueue({
|
controller.enqueue({
|
||||||
type: ChunkType.TEXT_START
|
type: ChunkType.TEXT_START
|
||||||
} as TextStartChunk)
|
} as TextStartChunk)
|
||||||
accumulatingText = true
|
accumulatingText = true
|
||||||
}
|
}
|
||||||
// logger.silly('enqueue TEXT_DELTA')
|
|
||||||
controller.enqueue({
|
controller.enqueue({
|
||||||
type: ChunkType.TEXT_DELTA,
|
type: ChunkType.TEXT_DELTA,
|
||||||
text: contentSource.content
|
text: mistralDelta.data?.[0]?.text
|
||||||
})
|
})
|
||||||
} else {
|
} else if (!mistralDelta.success) {
|
||||||
accumulatingText = false
|
if (contentSource.content) {
|
||||||
|
// logger.silly('since contentSource.content is trusy, try to enqueue TEXT_START and TEXT_DELTA')
|
||||||
|
if (!accumulatingText) {
|
||||||
|
// logger.silly('enqueue TEXT_START')
|
||||||
|
controller.enqueue({
|
||||||
|
type: ChunkType.TEXT_START
|
||||||
|
} as TextStartChunk)
|
||||||
|
accumulatingText = true
|
||||||
|
}
|
||||||
|
// logger.silly('enqueue TEXT_DELTA')
|
||||||
|
controller.enqueue({
|
||||||
|
type: ChunkType.TEXT_DELTA,
|
||||||
|
text: contentSource.content
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
accumulatingText = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理工具调用
|
// 处理工具调用
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import {
|
|||||||
} from '@google/genai'
|
} from '@google/genai'
|
||||||
import OpenAI, { AzureOpenAI } from 'openai'
|
import OpenAI, { AzureOpenAI } from 'openai'
|
||||||
import { Stream } from 'openai/streaming'
|
import { Stream } from 'openai/streaming'
|
||||||
|
import * as z from 'zod'
|
||||||
|
|
||||||
import { EndpointType } from './index'
|
import { EndpointType } from './index'
|
||||||
|
|
||||||
@ -260,3 +261,19 @@ export interface AwsBedrockSdkToolCall {
|
|||||||
input: any
|
input: any
|
||||||
toolUseId: string
|
toolUseId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const MistralDeltaTextSchema = z.object({
|
||||||
|
type: z.literal('text'),
|
||||||
|
text: z.string()
|
||||||
|
})
|
||||||
|
|
||||||
|
export const MistralDeltaThinkingSchema = z.object({
|
||||||
|
type: z.literal('thinking'),
|
||||||
|
thinking: z.array(MistralDeltaTextSchema)
|
||||||
|
})
|
||||||
|
|
||||||
|
export const MistralDeltaSchema = z.array(
|
||||||
|
z.discriminatedUnion('type', [MistralDeltaTextSchema, MistralDeltaThinkingSchema])
|
||||||
|
)
|
||||||
|
|
||||||
|
export type MistralDelta = z.infer<typeof MistralDeltaSchema>
|
||||||
|
|||||||
10
yarn.lock
10
yarn.lock
@ -8650,7 +8650,7 @@ __metadata:
|
|||||||
winston-daily-rotate-file: "npm:^5.0.0"
|
winston-daily-rotate-file: "npm:^5.0.0"
|
||||||
word-extractor: "npm:^1.0.4"
|
word-extractor: "npm:^1.0.4"
|
||||||
zipread: "npm:^1.3.3"
|
zipread: "npm:^1.3.3"
|
||||||
zod: "npm:^3.25.74"
|
zod: "npm:^4.0.0"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
@ -22669,10 +22669,10 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"zod@npm:^3.25.74":
|
"zod@npm:^4.0.0":
|
||||||
version: 3.25.74
|
version: 4.0.17
|
||||||
resolution: "zod@npm:3.25.74"
|
resolution: "zod@npm:4.0.17"
|
||||||
checksum: 10c0/59e38b046ac333b5bd1ba325a83b6798721227cbfb1e69dfc7159bd7824b904241ab923026edb714fafefec3624265ae374a70aee9a5a45b365bd31781ffa105
|
checksum: 10c0/c56ef4cc02f8f52be8724c5a8b338266202d68477c7606bee9b7299818b75c9adc27f16f4b6704a372f3e7578bd016f389de19bfec766564b7c39d0d327c540a
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user