mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-08 14:29:15 +08:00
feat: support openrouter gemini 2.5 flash image preview (#9587)
* feat: support openrouter gemini 2.5 flash image preview * feat: improve image content handling with type safety * fix: code fmt
This commit is contained in:
parent
92ab338640
commit
ce14d15ba3
@ -881,7 +881,9 @@ 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 !== '') ||
|
||||||
|
((choice.delta as OpenAISdkRawContentSource).images &&
|
||||||
|
Array.isArray((choice.delta as OpenAISdkRawContentSource).images)))
|
||||||
) {
|
) {
|
||||||
contentSource = choice.delta
|
contentSource = choice.delta
|
||||||
} else if ('message' in choice) {
|
} else if ('message' in choice) {
|
||||||
@ -979,6 +981,20 @@ export class OpenAIAPIClient extends OpenAIBaseClient<
|
|||||||
accumulatingText = false
|
accumulatingText = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理图片内容 (e.g. from OpenRouter Gemini image generation models)
|
||||||
|
if (contentSource.images && Array.isArray(contentSource.images)) {
|
||||||
|
controller.enqueue({
|
||||||
|
type: ChunkType.IMAGE_CREATED
|
||||||
|
})
|
||||||
|
controller.enqueue({
|
||||||
|
type: ChunkType.IMAGE_COMPLETE,
|
||||||
|
image: {
|
||||||
|
type: 'base64',
|
||||||
|
images: contentSource.images.map((image) => image.image_url?.url || '')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 处理工具调用
|
// 处理工具调用
|
||||||
if (contentSource.tool_calls) {
|
if (contentSource.tool_calls) {
|
||||||
for (const toolCall of contentSource.tool_calls) {
|
for (const toolCall of contentSource.tool_calls) {
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import {
|
|||||||
Tool
|
Tool
|
||||||
} from '@google/genai'
|
} from '@google/genai'
|
||||||
import OpenAI, { AzureOpenAI } from 'openai'
|
import OpenAI, { AzureOpenAI } from 'openai'
|
||||||
|
import { ChatCompletionContentPartImage } from 'openai/resources'
|
||||||
import { Stream } from 'openai/streaming'
|
import { Stream } from 'openai/streaming'
|
||||||
|
|
||||||
import { EndpointType } from './index'
|
import { EndpointType } from './index'
|
||||||
@ -107,8 +108,12 @@ export type OpenAISdkRawChunk =
|
|||||||
|
|
||||||
export type OpenAISdkRawOutput = Stream<OpenAI.Chat.Completions.ChatCompletionChunk> | OpenAI.ChatCompletion
|
export type OpenAISdkRawOutput = Stream<OpenAI.Chat.Completions.ChatCompletionChunk> | OpenAI.ChatCompletion
|
||||||
export type OpenAISdkRawContentSource =
|
export type OpenAISdkRawContentSource =
|
||||||
| OpenAI.Chat.Completions.ChatCompletionChunk.Choice.Delta
|
| (OpenAI.Chat.Completions.ChatCompletionChunk.Choice.Delta & {
|
||||||
| OpenAI.Chat.Completions.ChatCompletionMessage
|
images?: ChatCompletionContentPartImage[]
|
||||||
|
})
|
||||||
|
| (OpenAI.Chat.Completions.ChatCompletionMessage & {
|
||||||
|
images?: ChatCompletionContentPartImage[]
|
||||||
|
})
|
||||||
|
|
||||||
export type OpenAISdkMessageParam = OpenAI.Chat.Completions.ChatCompletionMessageParam
|
export type OpenAISdkMessageParam = OpenAI.Chat.Completions.ChatCompletionMessageParam
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user