diff --git a/packages/adapter-gemini/src/index.ts b/packages/adapter-gemini/src/index.ts index d6881cd5c..da2f7d205 100644 --- a/packages/adapter-gemini/src/index.ts +++ b/packages/adapter-gemini/src/index.ts @@ -50,6 +50,7 @@ export interface Config extends ChatLunaPlugin.Config { includeThoughts: boolean groundingContentDisplay: boolean useCamelCaseSystemInstruction: boolean + useCamelCaseMediaFields: boolean nonStreaming: boolean } @@ -86,6 +87,7 @@ export const Config: Schema = Schema.intersect([ groundingContentDisplay: Schema.boolean().default(false), imageGeneration: Schema.boolean().default(false), useCamelCaseSystemInstruction: Schema.boolean().default(false), + useCamelCaseMediaFields: Schema.boolean().default(false), nonStreaming: Schema.boolean().default(false) }) ]).i18n({ diff --git a/packages/adapter-gemini/src/locales/en-US.schema.yml b/packages/adapter-gemini/src/locales/en-US.schema.yml index 2d77aa172..d85e42985 100644 --- a/packages/adapter-gemini/src/locales/en-US.schema.yml +++ b/packages/adapter-gemini/src/locales/en-US.schema.yml @@ -22,4 +22,5 @@ $inner: codeExecution: 'Enable code execution tool' urlContext: 'Enable URL context retrieval tool' useCamelCaseSystemInstruction: 'Use camelCase systemInstruction instead of snake_case system_instruction' + useCamelCaseMediaFields: 'Use camelCase inlineData and mimeType instead of snake_case inline_data and mime_type' nonStreaming: 'Force disable streaming response. When enabled, requests will always be made in non-streaming mode, even if the stream parameter is configured.' diff --git a/packages/adapter-gemini/src/locales/zh-CN.schema.yml b/packages/adapter-gemini/src/locales/zh-CN.schema.yml index fb035b0ae..593070167 100644 --- a/packages/adapter-gemini/src/locales/zh-CN.schema.yml +++ b/packages/adapter-gemini/src/locales/zh-CN.schema.yml @@ -22,4 +22,5 @@ $inner: codeExecution: '为模型启用代码执行工具。(开启后将无法使用工具调用)' urlContext: '为模型启用 URL 内容获取工具。(开启后将无法使用工具调用)' useCamelCaseSystemInstruction: 使用大写的 systemInstruction 而不是小写的 system_instruction + useCamelCaseMediaFields: 使用大写的 inlineData 和 mimeType,而不是小写的 inline_data 和 mime_type nonStreaming: 强制不启用流式返回。开启后,将总是以非流式发起请求,即便配置了 stream 参数。 diff --git a/packages/adapter-gemini/src/utils.ts b/packages/adapter-gemini/src/utils.ts index 9f5a0c5ba..24b73d732 100644 --- a/packages/adapter-gemini/src/utils.ts +++ b/packages/adapter-gemini/src/utils.ts @@ -223,9 +223,7 @@ async function processGeminiImageContent( const mineType = url.match(/^data:([^;]+);base64,/)?.[1] ?? 'image/jpeg' const data = url.replace(/^data:image\/\w+;base64,/, '') - return { - inline_data: { data, mime_type: mineType } - } + return createGeminiInlineDataPart(plugin, data, mineType) } type GeminiFileLikeContent = MessageContentComplex & @@ -254,18 +252,33 @@ function isGeminiFileLikeContent( ) } +function createGeminiInlineDataPart( + plugin: ChatLunaPlugin, + data: string, + mimeType: string +) { + if ((plugin.config as Config).useCamelCaseMediaFields) { + return { + inlineData: { data, mimeType } + } + } + + return { + inline_data: { data, mime_type: mimeType } + } +} + async function processGeminiFileLikeContent( plugin: ChatLunaPlugin, part: GeminiFileLikeContent ) { try { const { buffer, mimeType } = await fetchFileLikeUrl(plugin, part) - return { - inline_data: { - data: buffer.toString('base64'), - mime_type: mimeType - } - } + return createGeminiInlineDataPart( + plugin, + buffer.toString('base64'), + mimeType + ) } catch (e) { logger.warn(`Failed to fetch ${part.type}`, e) return null