From eb6d7f93c2902d06ed4f25ce9bb214da592b3806 Mon Sep 17 00:00:00 2001 From: Raylan LIN Date: Fri, 10 Apr 2026 16:43:40 +0800 Subject: [PATCH 1/2] feat(image): add --seed, --width/--height, --prompt-optimizer, --aigc-watermark - Add --seed for reproducible generation - Add --width/--height for custom dimensions (512-2048, multiple of 8) - Add validation: both required together, range + divisibility check - Add --prompt-optimizer for auto prompt optimization - Add --aigc-watermark for AI content watermarking - Add apiDocs field - Update description: image-01 / image-01-live - Improve --aspect-ratio description - Add seed, dimensions, and optimizer examples --- src/command.ts | 3 +++ src/commands/image/generate.ts | 48 +++++++++++++++++++++++++++++++--- src/types/api.ts | 5 ++++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/command.ts b/src/command.ts index 7ccbbaf..8d89da8 100644 --- a/src/command.ts +++ b/src/command.ts @@ -14,6 +14,7 @@ export interface Command { usage?: string; options?: OptionDef[]; examples?: string[]; + apiDocs?: string; execute(config: Config, flags: GlobalFlags): Promise; } @@ -23,6 +24,7 @@ export interface CommandSpec { usage?: string; options?: OptionDef[]; examples?: string[]; + apiDocs?: string; run(config: Config, flags: GlobalFlags): Promise; } @@ -33,6 +35,7 @@ export function defineCommand(spec: CommandSpec): Command { usage: spec.usage, options: spec.options, examples: spec.examples, + apiDocs: spec.apiDocs, execute: spec.run, }; } diff --git a/src/commands/image/generate.ts b/src/commands/image/generate.ts index 6fda648..f697202 100644 --- a/src/commands/image/generate.ts +++ b/src/commands/image/generate.ts @@ -1,4 +1,6 @@ import { defineCommand } from '../../command'; +import { CLIError } from '../../errors/base'; +import { ExitCode } from '../../errors/codes'; import { requestJson } from '../../client/http'; import { imageEndpoint } from '../../client/endpoints'; import { downloadFile } from '../../files/download'; @@ -18,13 +20,19 @@ import { promptText, failIfMissing } from '../../utils/prompt'; export default defineCommand({ name: 'image generate', - description: 'Generate images (image-01)', + description: 'Generate images (image-01 / image-01-live)', + apiDocs: 'https://platform.minimax.io/docs/api-reference/image-generation-t2i', usage: 'mmx image generate --prompt [flags]', options: [ { flag: '--prompt ', description: 'Image description', required: true }, - { flag: '--aspect-ratio ', description: 'Aspect ratio (e.g. 16:9, 1:1)' }, + { flag: '--aspect-ratio ', description: 'Aspect ratio (e.g. 16:9, 1:1). Ignored if --width and --height are both specified.' }, { flag: '--n ', description: 'Number of images to generate (default: 1)', type: 'number' }, - { flag: '--subject-ref ', description: 'Subject reference (type=character,image=path)' }, + { flag: '--seed ', description: 'Random seed for reproducible generation (same seed + prompt = identical output)', type: 'number' }, + { flag: '--width ', 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' }, + { flag: '--height ', 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' }, + { flag: '--prompt-optimizer', description: 'Automatically optimize the prompt before generation for better results.' }, + { flag: '--aigc-watermark', description: 'Embed AI-generated content watermark in the output image.' }, + { flag: '--subject-ref ', description: 'Subject reference for character consistency. Format: type=character,image=path-or-url' }, { flag: '--out-dir ', description: 'Download images to directory' }, { flag: '--out-prefix ', description: 'Filename prefix (default: image)' }, ], @@ -32,6 +40,12 @@ export default defineCommand({ 'mmx image generate --prompt "A cat in a spacesuit on Mars" --aspect-ratio 16:9', 'mmx image generate --prompt "Logo design" --n 3 --out-dir ./generated/', 'mmx image generate --prompt "Mountain landscape" --quiet', + '# Reproducible output with seed', + 'mmx image generate --prompt "A castle" --seed 42', + '# Custom dimensions (must be 512–2048, multiple of 8)', + 'mmx image generate --prompt "Wide landscape" --width 1920 --height 1080', + '# Optimized prompt with watermark', + 'mmx image generate --prompt "sunset" --prompt-optimizer --aigc-watermark', ], async run(config: Config, flags: GlobalFlags) { let prompt = (flags.prompt ?? (flags._positional as string[]|undefined)?.[0]) as string | undefined; @@ -51,11 +65,39 @@ export default defineCommand({ } } + // Validate width/height + const width = flags.width as number | undefined; + const height = flags.height as number | undefined; + + if (width !== undefined && height === undefined) { + throw new CLIError('--width requires --height. Both must be specified together.', ExitCode.USAGE); + } + if (height !== undefined && width === undefined) { + throw new CLIError('--height requires --width. Both must be specified together.', ExitCode.USAGE); + } + if (width !== undefined && height !== undefined) { + const validateSize = (name: string, val: number) => { + if (val < 512 || val > 2048) { + throw new CLIError(`--${name} must be between 512 and 2048, got ${val}.`, ExitCode.USAGE); + } + if (val % 8 !== 0) { + throw new CLIError(`--${name} must be a multiple of 8, got ${val}.`, ExitCode.USAGE); + } + }; + validateSize('width', width); + validateSize('height', height); + } + const body: ImageRequest = { model: 'image-01', prompt, aspect_ratio: (flags.aspectRatio as string) || undefined, n: (flags.n as number) ?? 1, + seed: flags.seed as number | undefined, + width: width, + height: height, + prompt_optimizer: flags.promptOptimizer === true || undefined, + aigc_watermark: flags.aigcWatermark === true || undefined, }; if (flags.subjectRef) { diff --git a/src/types/api.ts b/src/types/api.ts index b62ebcf..e7fafc0 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -157,6 +157,11 @@ export interface ImageRequest { prompt: string; aspect_ratio?: string; n?: number; + seed?: number; + width?: number; + height?: number; + prompt_optimizer?: boolean; + aigc_watermark?: boolean; subject_reference?: Array<{ type: string; image_url?: string; From bdec8217f70e2fb7d303f494503f47bcc4bea162 Mon Sep 17 00:00:00 2001 From: tars90percent Date: Fri, 10 Apr 2026 19:38:20 +0800 Subject: [PATCH 2/2] fix: apiDocs path, clear aspect_ratio when width/height set - Change apiDocs from full URL to path (fixes broken URL in --help) - Clear aspect_ratio when both --width and --height are provided --- src/commands/image/generate.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/image/generate.ts b/src/commands/image/generate.ts index f697202..7ff5b5f 100644 --- a/src/commands/image/generate.ts +++ b/src/commands/image/generate.ts @@ -21,7 +21,7 @@ import { promptText, failIfMissing } from '../../utils/prompt'; export default defineCommand({ name: 'image generate', description: 'Generate images (image-01 / image-01-live)', - apiDocs: 'https://platform.minimax.io/docs/api-reference/image-generation-t2i', + apiDocs: '/docs/api-reference/image-generation-t2i', usage: 'mmx image generate --prompt [flags]', options: [ { flag: '--prompt ', description: 'Image description', required: true }, @@ -91,7 +91,7 @@ export default defineCommand({ const body: ImageRequest = { model: 'image-01', prompt, - aspect_ratio: (flags.aspectRatio as string) || undefined, + aspect_ratio: (width !== undefined && height !== undefined) ? undefined : ((flags.aspectRatio as string) || undefined), n: (flags.n as number) ?? 1, seed: flags.seed as number | undefined, width: width,