opencode-antigravity-img 0.1.2 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/README.md +21 -5
- package/package.json +1 -1
- package/src/api.ts +26 -1
- package/src/index.ts +20 -7
- package/src/types.ts +15 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.2.1] - 2026-01-28
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- Clarify in tool description that output is always JPEG format
|
|
12
|
+
- Fix default filename extension from `.png` to `.jpg`
|
|
13
|
+
- Remove unnecessary PNG check since API always returns JPEG
|
|
14
|
+
|
|
15
|
+
## [0.2.0] - 2026-01-27
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- Related plugins section in README linking to sibling plugins
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- Updated auth plugin link to correct repository (NoeFabris)
|
|
22
|
+
|
|
23
|
+
## [0.1.0] - 2026-01-26
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
- Initial release
|
|
27
|
+
- `generate_image` tool for generating images with Gemini 3 Pro Image model
|
|
28
|
+
- `image_quota` tool for checking remaining quota
|
|
29
|
+
- Support for aspect ratios: 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9
|
|
30
|
+
- Support for image sizes: 1K, 2K, 4K
|
|
31
|
+
- Automatic fallback between CloudCode API endpoints
|
package/README.md
CHANGED
|
@@ -43,10 +43,12 @@ Generate an image from a text prompt.
|
|
|
43
43
|
- `prompt` (required): Text description of the image to generate
|
|
44
44
|
- `filename` (optional): Output filename (default: `generated_<timestamp>.jpg`)
|
|
45
45
|
- `output_dir` (optional): Output directory (default: current working directory)
|
|
46
|
+
- `aspect_ratio` (optional): Image aspect ratio. Supported values: `1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`, `21:9` (default: `1:1`)
|
|
47
|
+
- `image_size` (optional): Image resolution. Supported values: `1K`, `2K`, `4K` (default: `1K`)
|
|
46
48
|
|
|
47
49
|
**Example:**
|
|
48
50
|
```
|
|
49
|
-
Generate
|
|
51
|
+
Generate a 16:9 landscape image of a sunset over mountains with a lake in the foreground
|
|
50
52
|
```
|
|
51
53
|
|
|
52
54
|
**Output:**
|
|
@@ -66,10 +68,24 @@ Check the remaining quota for the Gemini 3 Pro Image model.
|
|
|
66
68
|
## Image Details
|
|
67
69
|
|
|
68
70
|
- **Model**: Gemini 3 Pro Image
|
|
69
|
-
- **
|
|
70
|
-
-
|
|
71
|
+
- **Resolutions**:
|
|
72
|
+
- `1K`: 1024x1024 (default)
|
|
73
|
+
- `2K`: 2048x2048
|
|
74
|
+
- `4K`: 4096x4096
|
|
75
|
+
- **Aspect ratios**: `1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`, `21:9`
|
|
76
|
+
- **Format**: JPEG (always, regardless of filename extension)
|
|
71
77
|
- **Generation time**: 10-30 seconds
|
|
72
78
|
|
|
79
|
+
## Unsupported Parameters
|
|
80
|
+
|
|
81
|
+
The following parameters are documented in Google's API but are **not supported** by the Gemini 3 Pro Image model (they are Imagen-specific):
|
|
82
|
+
|
|
83
|
+
- `personGeneration` - Control generation of people in images
|
|
84
|
+
- `outputMimeType` - Output format selection (always returns JPEG)
|
|
85
|
+
- `compressionQuality` - JPEG compression control
|
|
86
|
+
|
|
87
|
+
These parameters may work with Imagen models but have no effect with Gemini 3 Pro Image.
|
|
88
|
+
|
|
73
89
|
## Quota
|
|
74
90
|
|
|
75
91
|
Image generation uses a separate quota from text models. The quota resets every 5 hours. Use the `image_quota` tool to check your remaining quota.
|
|
@@ -102,8 +118,8 @@ The plugin uses Google's CloudCode API with fallback endpoints:
|
|
|
102
118
|
|
|
103
119
|
## Related Plugins
|
|
104
120
|
|
|
105
|
-
- [opencode-antigravity-auth](https://
|
|
106
|
-
- [opencode-antigravity-
|
|
121
|
+
- [opencode-antigravity-auth](https://github.com/NoeFabris/opencode-antigravity-auth) - Authentication (required)
|
|
122
|
+
- [opencode-antigravity-web](https://github.com/ominiverdi/opencode-antigravity-web) - Web search and URL reading
|
|
107
123
|
|
|
108
124
|
## License
|
|
109
125
|
|
package/package.json
CHANGED
package/src/api.ts
CHANGED
|
@@ -15,6 +15,7 @@ import type {
|
|
|
15
15
|
CloudCodeQuotaResponse,
|
|
16
16
|
GenerateContentResponse,
|
|
17
17
|
ImageGenerationResult,
|
|
18
|
+
ImageGenerationOptions,
|
|
18
19
|
QuotaInfo,
|
|
19
20
|
} from "./types";
|
|
20
21
|
|
|
@@ -149,12 +150,34 @@ export async function getImageModelQuota(account: Account): Promise<QuotaInfo |
|
|
|
149
150
|
}
|
|
150
151
|
}
|
|
151
152
|
|
|
153
|
+
/**
|
|
154
|
+
* Build imageConfig from options
|
|
155
|
+
*/
|
|
156
|
+
function buildImageConfig(options?: ImageGenerationOptions): ImageGenerationOptions | undefined {
|
|
157
|
+
if (!options) return undefined;
|
|
158
|
+
|
|
159
|
+
const { aspectRatio, imageSize } = options;
|
|
160
|
+
|
|
161
|
+
// Only include if at least one option is set
|
|
162
|
+
if (!aspectRatio && !imageSize) {
|
|
163
|
+
return undefined;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const imageConfig: ImageGenerationOptions = {};
|
|
167
|
+
|
|
168
|
+
if (aspectRatio) imageConfig.aspectRatio = aspectRatio;
|
|
169
|
+
if (imageSize) imageConfig.imageSize = imageSize;
|
|
170
|
+
|
|
171
|
+
return imageConfig;
|
|
172
|
+
}
|
|
173
|
+
|
|
152
174
|
/**
|
|
153
175
|
* Generate an image using the Gemini 3 Pro Image model
|
|
154
176
|
*/
|
|
155
177
|
export async function generateImage(
|
|
156
178
|
account: Account,
|
|
157
|
-
prompt: string
|
|
179
|
+
prompt: string,
|
|
180
|
+
options?: ImageGenerationOptions
|
|
158
181
|
): Promise<ImageGenerationResult> {
|
|
159
182
|
try {
|
|
160
183
|
// Get access token
|
|
@@ -172,6 +195,7 @@ export async function generateImage(
|
|
|
172
195
|
}
|
|
173
196
|
|
|
174
197
|
// Build request
|
|
198
|
+
const imageConfig = buildImageConfig(options);
|
|
175
199
|
const requestBody = {
|
|
176
200
|
project: projectId,
|
|
177
201
|
requestId: `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
|
@@ -183,6 +207,7 @@ export async function generateImage(
|
|
|
183
207
|
session_id: `sess_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
|
184
208
|
generationConfig: {
|
|
185
209
|
responseModalities: ["TEXT", "IMAGE"],
|
|
210
|
+
...(imageConfig && { imageConfig }),
|
|
186
211
|
},
|
|
187
212
|
},
|
|
188
213
|
};
|
package/src/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ import * as fs from "fs/promises";
|
|
|
3
3
|
import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
|
|
4
4
|
import { join, dirname } from "path";
|
|
5
5
|
import { CONFIG_PATHS, COMMAND_DIR, COMMAND_FILE, COMMAND_CONTENT, IMAGE_MODEL } from "./constants";
|
|
6
|
-
import type { AccountsConfig, Account } from "./types";
|
|
6
|
+
import type { AccountsConfig, Account, ImageGenerationOptions, AspectRatio, ImageSize } from "./types";
|
|
7
7
|
import { generateImage, getImageModelQuota } from "./api";
|
|
8
8
|
|
|
9
9
|
// Create command file for opencode discovery
|
|
@@ -72,20 +72,29 @@ export const plugin: Plugin = async (ctx) => {
|
|
|
72
72
|
description:
|
|
73
73
|
"Generate an image using Gemini 3 Pro Image model. " +
|
|
74
74
|
"Provide a text prompt describing the image you want. " +
|
|
75
|
+
"IMPORTANT: Output is always JPEG format regardless of filename extension. " +
|
|
75
76
|
"Returns the path to the generated image file.",
|
|
76
77
|
args: {
|
|
77
78
|
prompt: tool.schema.string().describe("Text description of the image to generate"),
|
|
78
79
|
filename: tool.schema
|
|
79
80
|
.string()
|
|
80
81
|
.optional()
|
|
81
|
-
.describe("Output filename (default: generated_<timestamp>.
|
|
82
|
+
.describe("Output filename (default: generated_<timestamp>.jpg). Note: format is always JPEG regardless of extension"),
|
|
82
83
|
output_dir: tool.schema
|
|
83
84
|
.string()
|
|
84
85
|
.optional()
|
|
85
86
|
.describe("Output directory (default: current working directory)"),
|
|
87
|
+
aspect_ratio: tool.schema
|
|
88
|
+
.string()
|
|
89
|
+
.optional()
|
|
90
|
+
.describe("Aspect ratio: 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9 (default: 1:1)"),
|
|
91
|
+
image_size: tool.schema
|
|
92
|
+
.string()
|
|
93
|
+
.optional()
|
|
94
|
+
.describe("Image resolution: 1K, 2K, 4K (default: 1K)"),
|
|
86
95
|
},
|
|
87
96
|
async execute(args, context) {
|
|
88
|
-
const { prompt, filename, output_dir } = args;
|
|
97
|
+
const { prompt, filename, output_dir, aspect_ratio, image_size } = args;
|
|
89
98
|
|
|
90
99
|
if (!prompt?.trim()) {
|
|
91
100
|
return "Error: Please provide a prompt describing the image to generate.";
|
|
@@ -105,17 +114,21 @@ export const plugin: Plugin = async (ctx) => {
|
|
|
105
114
|
|
|
106
115
|
context.metadata({ title: "Generating image..." });
|
|
107
116
|
|
|
117
|
+
// Build generation options
|
|
118
|
+
const options: ImageGenerationOptions = {};
|
|
119
|
+
if (aspect_ratio) options.aspectRatio = aspect_ratio as AspectRatio;
|
|
120
|
+
if (image_size) options.imageSize = image_size as ImageSize;
|
|
121
|
+
|
|
108
122
|
// Generate image
|
|
109
|
-
const result = await generateImage(account, prompt);
|
|
123
|
+
const result = await generateImage(account, prompt, Object.keys(options).length > 0 ? options : undefined);
|
|
110
124
|
|
|
111
125
|
if (!result.success || !result.imageData) {
|
|
112
126
|
return `Error generating image: ${result.error || "Unknown error"}`;
|
|
113
127
|
}
|
|
114
128
|
|
|
115
|
-
// Determine output path
|
|
129
|
+
// Determine output path (always JPEG regardless of extension)
|
|
116
130
|
const dir = output_dir || ctx.directory;
|
|
117
|
-
const
|
|
118
|
-
const name = filename || `generated_${Date.now()}.${ext}`;
|
|
131
|
+
const name = filename || `generated_${Date.now()}.jpg`;
|
|
119
132
|
const outputPath = join(dir, name);
|
|
120
133
|
|
|
121
134
|
// Ensure directory exists
|
package/src/types.ts
CHANGED
|
@@ -37,7 +37,20 @@ export interface ModelInfo {
|
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
// Image generation
|
|
40
|
+
// Image generation options
|
|
41
|
+
export type AspectRatio = "1:1" | "2:3" | "3:2" | "3:4" | "4:3" | "4:5" | "5:4" | "9:16" | "16:9" | "21:9";
|
|
42
|
+
export type ImageSize = "1K" | "2K" | "4K";
|
|
43
|
+
|
|
44
|
+
export interface ImageConfig {
|
|
45
|
+
aspectRatio?: AspectRatio;
|
|
46
|
+
imageSize?: ImageSize;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface ImageGenerationOptions {
|
|
50
|
+
aspectRatio?: AspectRatio;
|
|
51
|
+
imageSize?: ImageSize;
|
|
52
|
+
}
|
|
53
|
+
|
|
41
54
|
export interface GenerateContentRequest {
|
|
42
55
|
project: string;
|
|
43
56
|
requestId: string;
|
|
@@ -52,6 +65,7 @@ export interface GenerateContentRequest {
|
|
|
52
65
|
session_id: string;
|
|
53
66
|
generationConfig: {
|
|
54
67
|
responseModalities: string[];
|
|
68
|
+
imageConfig?: ImageConfig;
|
|
55
69
|
};
|
|
56
70
|
};
|
|
57
71
|
}
|