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:
yyhhyyyyyy 2025-08-27 13:03:50 +08:00 committed by GitHub
parent 92ab338640
commit ce14d15ba3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 3 deletions

View File

@ -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) {

View File

@ -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