Skip to content

Commit da13680

Browse files
committed
feat: add aspect ratio configuration for Gemini image generation
1 parent 8561731 commit da13680

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

backend/src/extensions/module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ import { DuckduckgoWebSearchExtension } from './tools/duckduckgo-web-search';
3232
import { FilesExtension } from './tools/files';
3333
import { FilesConversationExtension } from './tools/files-conversation';
3434
import { FilesVisionExtension } from './tools/files-vision';
35+
import { GeminiImageExtension } from './tools/gemini-image';
3536
import { GPTImage1Extension } from './tools/gpt-image-1';
3637
import { GroundingWithBingSearchExtension } from './tools/grounding-with-bing';
3738
import { MCPToolsExtension } from './tools/mcp-tools';
3839
import { OpenApiExtension } from './tools/open-api';
3940
import { WholeFilesExtension } from './tools/whole-files-conversation';
40-
import { GeminiImageExtension } from './tools/gemini-image';
4141

4242
const extensionClassSuffix = 'Extension';
4343

backend/src/extensions/tools/gemini-image.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
import { createGoogleGenerativeAI } from '@ai-sdk/google';
12
import { forwardRef, Inject, Logger } from '@nestjs/common';
23
import { CommandBus } from '@nestjs/cqrs';
4+
import { generateText } from 'ai';
35
import * as uuid from 'uuid';
46
import { z } from 'zod';
5-
import { generateText } from 'ai';
6-
import { createGoogleGenerativeAI } from '@ai-sdk/google';
77
import { AuthService } from 'src/domain/auth';
88
import { ChatContext, ChatMiddleware, ChatNextDelegate, GetContext, NamedStructuredTool } from 'src/domain/chat';
99
import { Extension, ExtensionConfiguration, ExtensionEntity, ExtensionSpec } from 'src/domain/extensions';
@@ -43,6 +43,14 @@ export class GeminiImageExtension implements Extension<GeminiImageExtensionConfi
4343
examples: ['gemini-2.5-flash-image', 'gemini-3-pro-image-preview'],
4444
showInList: true,
4545
},
46+
aspectRatio: {
47+
type: 'string',
48+
title: 'Aspect Ratio',
49+
required: false,
50+
format: 'select',
51+
examples: ['1:1', '2:3', '3:2', '3:4', '4:3', '4:5', '5:4', '9:16', '16:9', '21:9'],
52+
showInList: true,
53+
},
4654
},
4755
};
4856
}
@@ -95,7 +103,7 @@ class InternalTool extends NamedStructuredTool {
95103

96104
protected async _call({ prompt }: z.infer<typeof this.schema>): Promise<string> {
97105
try {
98-
const { apiKey, modelName } = this.configuration;
106+
const { apiKey, modelName, aspectRatio } = this.configuration;
99107

100108
const googleProvider = createGoogleGenerativeAI({
101109
apiKey,
@@ -104,9 +112,17 @@ class InternalTool extends NamedStructuredTool {
104112
const result = await generateText({
105113
model: googleProvider(modelName),
106114
prompt,
115+
providerOptions: {
116+
google: {
117+
imageConfig: {
118+
aspectRatio: aspectRatio || '1:1',
119+
},
120+
},
121+
},
107122
});
108123

109124
const file = result.files?.find((f) => f.mediaType?.startsWith('image/'));
125+
110126
if (!file) {
111127
throw new Error('No image file received from Google');
112128
}
@@ -136,4 +152,5 @@ class InternalTool extends NamedStructuredTool {
136152
export type GeminiImageExtensionConfiguration = ExtensionConfiguration & {
137153
apiKey: string;
138154
modelName: string;
155+
aspectRatio?: '1:1' | '2:3' | '3:2' | '3:4' | '4:3' | '4:5' | '5:4' | '9:16' | '16:9' | '21:9';
139156
};

0 commit comments

Comments
 (0)