mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-19 14:41:24 +08:00
parent
cbf1d461f0
commit
97519d96d7
@ -93,7 +93,7 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => {
|
|||||||
const getNewPainting = useCallback(() => {
|
const getNewPainting = useCallback(() => {
|
||||||
return {
|
return {
|
||||||
...DEFAULT_PAINTING,
|
...DEFAULT_PAINTING,
|
||||||
model: mode === 'aihubmix_image_generate' ? 'gpt-image-1' : 'V_3',
|
model: mode === 'aihubmix_image_generate' ? 'gemini-3-pro-image-preview' : 'V_3',
|
||||||
id: uuid()
|
id: uuid()
|
||||||
}
|
}
|
||||||
}, [mode])
|
}, [mode])
|
||||||
@ -201,6 +201,74 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => {
|
|||||||
updatePaintingState({ files: validFiles, urls: validFiles.map((file) => file.name) })
|
updatePaintingState({ files: validFiles, urls: validFiles.map((file) => file.name) })
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
} else if (painting.model === 'gemini-3-pro-image-preview') {
|
||||||
|
const geminiUrl = `${aihubmixProvider.apiHost}/gemini/v1beta/models/gemini-3-pro-image-preview:streamGenerateContent`
|
||||||
|
const geminiHeaders = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'x-goog-api-key': aihubmixProvider.apiKey
|
||||||
|
}
|
||||||
|
|
||||||
|
const requestBody = {
|
||||||
|
contents: [
|
||||||
|
{
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
text: prompt
|
||||||
|
}
|
||||||
|
],
|
||||||
|
role: 'user'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
generationConfig: {
|
||||||
|
responseModalities: ['TEXT', 'IMAGE'],
|
||||||
|
imageConfig: {
|
||||||
|
aspectRatio: painting.aspectRatio?.replace('ASPECT_', '').replace('_', ':') || '1:1',
|
||||||
|
imageSize: painting.imageSize || '1k'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.silly(`Gemini Request: ${JSON.stringify(requestBody)}`)
|
||||||
|
|
||||||
|
const response = await fetch(geminiUrl, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: geminiHeaders,
|
||||||
|
body: JSON.stringify(requestBody)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorData = await response.json()
|
||||||
|
logger.error('Gemini API Error:', errorData)
|
||||||
|
throw new Error(errorData.error?.message || '生成图像失败')
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json()
|
||||||
|
logger.silly(`Gemini API Response: ${JSON.stringify(data)}`)
|
||||||
|
|
||||||
|
// Handle array response (stream) or single object
|
||||||
|
const responseItems = Array.isArray(data) ? data : [data]
|
||||||
|
const base64s: string[] = []
|
||||||
|
|
||||||
|
responseItems.forEach((item) => {
|
||||||
|
item.candidates?.forEach((candidate: any) => {
|
||||||
|
candidate.content?.parts?.forEach((part: any) => {
|
||||||
|
if (part.inlineData?.data) {
|
||||||
|
base64s.push(part.inlineData.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (base64s.length > 0) {
|
||||||
|
const validFiles = await Promise.all(
|
||||||
|
base64s.map(async (base64: string) => {
|
||||||
|
return await window.api.file.saveBase64Image(base64)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
await FileManager.addFiles(validFiles)
|
||||||
|
updatePaintingState({ files: validFiles, urls: validFiles.map((file) => file.name) })
|
||||||
|
}
|
||||||
|
return
|
||||||
} else if (painting.model === 'V_3') {
|
} else if (painting.model === 'V_3') {
|
||||||
// V3 API uses different endpoint and parameters format
|
// V3 API uses different endpoint and parameters format
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
|
|||||||
@ -72,6 +72,7 @@ export const createModeConfigs = (): Record<AihubmixMode, ConfigItem[]> => {
|
|||||||
label: 'Gemini',
|
label: 'Gemini',
|
||||||
title: 'Gemini',
|
title: 'Gemini',
|
||||||
options: [
|
options: [
|
||||||
|
{ label: 'Nano Banana Pro', value: 'gemini-3-pro-image-preview' },
|
||||||
{ label: 'imagen-4.0-preview', value: 'imagen-4.0-generate-preview-06-06' },
|
{ label: 'imagen-4.0-preview', value: 'imagen-4.0-generate-preview-06-06' },
|
||||||
{ label: 'imagen-4.0-ultra', value: 'imagen-4.0-ultra-generate-preview-06-06' }
|
{ label: 'imagen-4.0-ultra', value: 'imagen-4.0-ultra-generate-preview-06-06' }
|
||||||
]
|
]
|
||||||
@ -224,7 +225,20 @@ export const createModeConfigs = (): Record<AihubmixMode, ConfigItem[]> => {
|
|||||||
{ label: '16:9', value: 'ASPECT_16_9' }
|
{ label: '16:9', value: 'ASPECT_16_9' }
|
||||||
],
|
],
|
||||||
initialValue: 'ASPECT_1_1',
|
initialValue: 'ASPECT_1_1',
|
||||||
condition: (painting) => Boolean(painting.model?.startsWith('imagen-'))
|
condition: (painting) =>
|
||||||
|
Boolean(painting.model?.startsWith('imagen-') || painting.model === 'gemini-3-pro-image-preview')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
key: 'imageSize',
|
||||||
|
title: 'paintings.image.size',
|
||||||
|
options: [
|
||||||
|
{ label: '1K', value: '1K' },
|
||||||
|
{ label: '2K', value: '2K' },
|
||||||
|
{ label: '4K', value: '4K' }
|
||||||
|
],
|
||||||
|
initialValue: '1K',
|
||||||
|
condition: (painting) => painting.model === 'gemini-3-pro-image-preview'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'select',
|
type: 'select',
|
||||||
@ -398,7 +412,7 @@ export const createModeConfigs = (): Record<AihubmixMode, ConfigItem[]> => {
|
|||||||
// 几种默认的绘画配置
|
// 几种默认的绘画配置
|
||||||
export const DEFAULT_PAINTING: PaintingAction = {
|
export const DEFAULT_PAINTING: PaintingAction = {
|
||||||
id: 'aihubmix_1',
|
id: 'aihubmix_1',
|
||||||
model: 'gpt-image-1',
|
model: 'gemini-3-pro-image-preview',
|
||||||
aspectRatio: 'ASPECT_1_1',
|
aspectRatio: 'ASPECT_1_1',
|
||||||
numImages: 1,
|
numImages: 1,
|
||||||
styleType: 'AUTO',
|
styleType: 'AUTO',
|
||||||
@ -420,5 +434,6 @@ export const DEFAULT_PAINTING: PaintingAction = {
|
|||||||
moderation: 'auto',
|
moderation: 'auto',
|
||||||
n: 1,
|
n: 1,
|
||||||
numberOfImages: 4,
|
numberOfImages: 4,
|
||||||
safetyTolerance: 6
|
safetyTolerance: 6,
|
||||||
|
imageSize: '1K'
|
||||||
}
|
}
|
||||||
|
|||||||
@ -320,6 +320,7 @@ export interface GeneratePainting extends PaintingParams {
|
|||||||
safetyTolerance?: number
|
safetyTolerance?: number
|
||||||
width?: number
|
width?: number
|
||||||
height?: number
|
height?: number
|
||||||
|
imageSize?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EditPainting extends PaintingParams {
|
export interface EditPainting extends PaintingParams {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user