Skip to content

Commit cbebc42

Browse files
Merge pull request #75 from raylanlin/pr/image
feat(image): add --seed, --width/--height, --prompt-optimizer, --aigc-watermark
2 parents 9946f25 + bdec821 commit cbebc42

2 files changed

Lines changed: 51 additions & 4 deletions

File tree

src/commands/image/generate.ts

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { defineCommand } from '../../command';
2+
import { CLIError } from '../../errors/base';
3+
import { ExitCode } from '../../errors/codes';
24
import { requestJson } from '../../client/http';
35
import { imageEndpoint } from '../../client/endpoints';
46
import { downloadFile } from '../../files/download';
@@ -18,20 +20,32 @@ import { promptText, failIfMissing } from '../../utils/prompt';
1820

1921
export default defineCommand({
2022
name: 'image generate',
21-
description: 'Generate images (image-01)',
23+
description: 'Generate images (image-01 / image-01-live)',
24+
apiDocs: '/docs/api-reference/image-generation-t2i',
2225
usage: 'mmx image generate --prompt <text> [flags]',
2326
options: [
2427
{ flag: '--prompt <text>', description: 'Image description', required: true },
25-
{ flag: '--aspect-ratio <ratio>', description: 'Aspect ratio (e.g. 16:9, 1:1)' },
28+
{ flag: '--aspect-ratio <ratio>', description: 'Aspect ratio (e.g. 16:9, 1:1). Ignored if --width and --height are both specified.' },
2629
{ flag: '--n <count>', description: 'Number of images to generate (default: 1)', type: 'number' },
27-
{ flag: '--subject-ref <params>', description: 'Subject reference (type=character,image=path)' },
30+
{ flag: '--seed <n>', description: 'Random seed for reproducible generation (same seed + prompt = identical output)', type: 'number' },
31+
{ flag: '--width <px>', description: 'Custom width in pixels. Range [512, 2048], must be multiple of 8. Only effective for image-01 model. Overrides --aspect-ratio if set.', type: 'number' },
32+
{ flag: '--height <px>', description: 'Custom height in pixels. Range [512, 2048], must be multiple of 8. Only effective for image-01 model. Overrides --aspect-ratio if set.', type: 'number' },
33+
{ flag: '--prompt-optimizer', description: 'Automatically optimize the prompt before generation for better results.' },
34+
{ flag: '--aigc-watermark', description: 'Embed AI-generated content watermark in the output image.' },
35+
{ flag: '--subject-ref <params>', description: 'Subject reference for character consistency. Format: type=character,image=path-or-url' },
2836
{ flag: '--out-dir <dir>', description: 'Download images to directory' },
2937
{ flag: '--out-prefix <prefix>', description: 'Filename prefix (default: image)' },
3038
],
3139
examples: [
3240
'mmx image generate --prompt "A cat in a spacesuit on Mars" --aspect-ratio 16:9',
3341
'mmx image generate --prompt "Logo design" --n 3 --out-dir ./generated/',
3442
'mmx image generate --prompt "Mountain landscape" --quiet',
43+
'# Reproducible output with seed',
44+
'mmx image generate --prompt "A castle" --seed 42',
45+
'# Custom dimensions (must be 512–2048, multiple of 8)',
46+
'mmx image generate --prompt "Wide landscape" --width 1920 --height 1080',
47+
'# Optimized prompt with watermark',
48+
'mmx image generate --prompt "sunset" --prompt-optimizer --aigc-watermark',
3549
],
3650
async run(config: Config, flags: GlobalFlags) {
3751
let prompt = (flags.prompt ?? (flags._positional as string[]|undefined)?.[0]) as string | undefined;
@@ -51,11 +65,39 @@ export default defineCommand({
5165
}
5266
}
5367

68+
// Validate width/height
69+
const width = flags.width as number | undefined;
70+
const height = flags.height as number | undefined;
71+
72+
if (width !== undefined && height === undefined) {
73+
throw new CLIError('--width requires --height. Both must be specified together.', ExitCode.USAGE);
74+
}
75+
if (height !== undefined && width === undefined) {
76+
throw new CLIError('--height requires --width. Both must be specified together.', ExitCode.USAGE);
77+
}
78+
if (width !== undefined && height !== undefined) {
79+
const validateSize = (name: string, val: number) => {
80+
if (val < 512 || val > 2048) {
81+
throw new CLIError(`--${name} must be between 512 and 2048, got ${val}.`, ExitCode.USAGE);
82+
}
83+
if (val % 8 !== 0) {
84+
throw new CLIError(`--${name} must be a multiple of 8, got ${val}.`, ExitCode.USAGE);
85+
}
86+
};
87+
validateSize('width', width);
88+
validateSize('height', height);
89+
}
90+
5491
const body: ImageRequest = {
5592
model: 'image-01',
5693
prompt,
57-
aspect_ratio: (flags.aspectRatio as string) || undefined,
94+
aspect_ratio: (width !== undefined && height !== undefined) ? undefined : ((flags.aspectRatio as string) || undefined),
5895
n: (flags.n as number) ?? 1,
96+
seed: flags.seed as number | undefined,
97+
width: width,
98+
height: height,
99+
prompt_optimizer: flags.promptOptimizer === true || undefined,
100+
aigc_watermark: flags.aigcWatermark === true || undefined,
59101
};
60102

61103
if (flags.subjectRef) {

src/types/api.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ export interface ImageRequest {
157157
prompt: string;
158158
aspect_ratio?: string;
159159
n?: number;
160+
seed?: number;
161+
width?: number;
162+
height?: number;
163+
prompt_optimizer?: boolean;
164+
aigc_watermark?: boolean;
160165
subject_reference?: Array<{
161166
type: string;
162167
image_url?: string;

0 commit comments

Comments
 (0)