@remixmate/cli 0.9.19 → 0.9.21

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/README.md CHANGED
@@ -165,8 +165,8 @@ This project contains 11 AI media generation skills covering the full pipeline f
165
165
  │ export-jianying Assets → Jianying draft ZIP │
166
166
  ├─────────────────────────────────────────────────────────────┤
167
167
  │ Atomic Skills │
168
- │ gen-image Text/Image-to-image (Seedream / Gemini)
169
- │ gen-video Text-to-video (Seedance / Veo)
168
+ │ gen-image Text/Image-to-image (Seedream 5.0)
169
+ │ gen-video Text-to-video (Seedance 2.0)
170
170
  │ gen-voice Text-to-speech (Minimax TTS) │
171
171
  │ gen-digital-human Talking-head (Jimeng / Feiying) │
172
172
  ├─────────────────────────────────────────────────────────────┤
@@ -203,8 +203,8 @@ This project contains 11 AI media generation skills covering the full pipeline f
203
203
 
204
204
  | Skill | Type | Description | Runtime / entry |
205
205
  |-------|------|-------------|-----------------|
206
- | gen-image | atomic | Text/Image-to-image (Seedream, Gemini) | http handler |
207
- | gen-video | atomic | Text-to-video (Seedance, Veo) | http handler |
206
+ | gen-image | atomic | Text/Image-to-image (Seedream 5.0 Lite / Pro) | http handler |
207
+ | gen-video | atomic | Text-to-video (Seedance 2.0, three tiers) | http handler |
208
208
  | gen-voice | atomic | Text-to-speech (Minimax TTS) | http handler |
209
209
  | gen-digital-human | atomic | Talking-head (Jimeng / Feiying) | http handler |
210
210
  | gen-script | orchestration | Topic → Video DSL JSON | python `scripts/gen_script.py` |
@@ -296,8 +296,8 @@ remixmate template-registry --list-templates
296
296
  ### Quick start
297
297
 
298
298
  ```
299
- @skills/gen-image/SKILL.md Generate an image of a panda, 9:16, using gemini, Chinese-painting style + follow this doc strictly
300
- @skills/gen-video/SKILL.md Generate a video of a panda running in a bamboo forest, 9:16, 6 seconds, using veo + follow this doc strictly
299
+ @skills/gen-image/SKILL.md Generate an image of a panda, 9:16, using seedream-pro, Chinese-painting style + follow this doc strictly
300
+ @skills/gen-video/SKILL.md Generate a video of a panda running in a bamboo forest, 9:16, 6 seconds, using seedance-mini + follow this doc strictly
301
301
  @skills/gen-voice/SKILL.md Generate a voiceover introducing panda habits, around 100 words + follow this doc strictly
302
302
  @skills/gen-digital-human/SKILL.md Get the digital human list + follow this doc strictly
303
303
  @skills/template-registry/SKILL.md Get the template list + follow this doc strictly
package/README.zh-CN.md CHANGED
@@ -124,8 +124,8 @@ Python 技能(12 个中的 8 个)需要 `python3 >= 3.10`。`web-screenshot`
124
124
  │ export-jianying 素材 → 剪映草稿 ZIP │
125
125
  ├─────────────────────────────────────────────────────────────┤
126
126
  │ 原子层 Skills │
127
- │ gen-image 文生图 / 图生图(Seedream / Gemini
128
- │ gen-video 文生视频(Seedance / Veo
127
+ │ gen-image 文生图 / 图生图(Seedream 5.0
128
+ │ gen-video 文生视频(Seedance 2.0
129
129
  │ gen-voice 语音合成(Minimax TTS) │
130
130
  │ gen-digital-human 数字人口播(即梦 / 飞影) │
131
131
  ├─────────────────────────────────────────────────────────────┤
@@ -162,8 +162,8 @@ Python 技能(12 个中的 8 个)需要 `python3 >= 3.10`。`web-screenshot`
162
162
 
163
163
  | 技能 | 类型 | 说明 | 运行方式 / entry |
164
164
  |------|------|------|------------------|
165
- | gen-image | 原子 | 文生图 / 图生图(Seedream、Gemini) | http handler |
166
- | gen-video | 原子 | 文生视频(Seedance、Veo) | http handler |
165
+ | gen-image | 原子 | 文生图 / 图生图(Seedream 5.0 Lite / Pro) | http handler |
166
+ | gen-video | 原子 | 文生视频(Seedance 2.0 三档) | http handler |
167
167
  | gen-voice | 原子 | 语音合成(Minimax TTS) | http handler |
168
168
  | gen-digital-human | 原子 | 数字人口播(即梦 / 飞影) | http handler |
169
169
  | gen-script | 编排 | 主题 → Video DSL JSON | python `scripts/gen_script.py` |
@@ -232,8 +232,8 @@ remixmate template-registry --list-templates
232
232
  ### 快速体验
233
233
 
234
234
  ```
235
- @skills/gen-image/SKILL.md 生成一张熊猫的图片,9:16,调用gemini,国画风 + 严格按该文档执行
236
- @skills/gen-video/SKILL.md 生成一段熊猫在竹林奔跑的视频,9:16,长度6秒,调用veo + 严格按该文档执行
235
+ @skills/gen-image/SKILL.md 生成一张熊猫的图片,9:16,调用 seedream-pro,国画风 + 严格按该文档执行
236
+ @skills/gen-video/SKILL.md 生成一段熊猫在竹林奔跑的视频,9:16,长度6秒,用 seedance-mini + 严格按该文档执行
237
237
  @skills/gen-voice/SKILL.md 生成一段语音,介绍熊猫的习性,大概100字左右 + 严格按该文档执行
238
238
  @skills/gen-digital-human/SKILL.md 获取数字人列表 + 严格按该文档执行
239
239
  @skills/template-registry/SKILL.md 获取模版列表 + 严格按该文档执行
@@ -18,6 +18,9 @@ export interface ModelConstraints {
18
18
  durationMax?: number;
19
19
  durationDefault?: number;
20
20
  refImageMax?: number;
21
+ /** Omni-modal reference caps (Seedance 2.0): videos and audio clips per request. */
22
+ refVideoMax?: number;
23
+ refAudioMax?: number;
21
24
  sizes?: string[];
22
25
  /** aspect-ratio → [width, height] pixel preset (Seedream). Per model: the same
23
26
  * ratio maps to different pixels on different Seedream variants. */
@@ -9,7 +9,8 @@
9
9
  * through and is validated by the backend).
10
10
  * - --size accepts a WxH string (→ width/height) or an aspect-ratio preset key
11
11
  * (→ aspectRatio; for Seedream models ab-api maps the preset to pixels).
12
- * - --resolution maps to the Gemini `size` tier (1K/2K/4K); ignored by others.
12
+ * - --resolution is accepted but inert: it only ever fed the Gemini `size` tier,
13
+ * and Gemini is not wired up on the gateway, so we no longer send it.
13
14
  * - Reference images: HTTPS URLs and data: URIs pass through; local paths are
14
15
  * read and base64-encoded into a data: URI.
15
16
  * - Async response (generationId + status:'generating'/'pending') is polled
@@ -9,7 +9,8 @@
9
9
  * through and is validated by the backend).
10
10
  * - --size accepts a WxH string (→ width/height) or an aspect-ratio preset key
11
11
  * (→ aspectRatio; for Seedream models ab-api maps the preset to pixels).
12
- * - --resolution maps to the Gemini `size` tier (1K/2K/4K); ignored by others.
12
+ * - --resolution is accepted but inert: it only ever fed the Gemini `size` tier,
13
+ * and Gemini is not wired up on the gateway, so we no longer send it.
13
14
  * - Reference images: HTTPS URLs and data: URIs pass through; local paths are
14
15
  * read and base64-encoded into a data: URI.
15
16
  * - Async response (generationId + status:'generating'/'pending') is polled
@@ -48,7 +49,6 @@ export async function genImage(input, ctxIn) {
48
49
  const model = descriptor?.id ?? requested ?? defaultModel(caps.image)?.id ?? '';
49
50
  const size = input.size ?? '1:1';
50
51
  const n = toNumber(input.n, 'n') ?? 1;
51
- const resolution = input.resolution ?? '1K';
52
52
  const seed = toNumber(input.seed, 'seed');
53
53
  const imageStrength = toNumber(input.image_strength, 'image_strength');
54
54
  const guidanceScale = toNumber(input.guidance_scale, 'guidance_scale');
@@ -76,8 +76,8 @@ export async function genImage(input, ctxIn) {
76
76
  if (watermark !== undefined)
77
77
  payload.watermark = watermark;
78
78
  // --size as WxH → explicit pixels; otherwise treat as an aspect-ratio preset.
79
- // ab-api maps an aspect-ratio preset to pixels for Seedream and uses it directly
80
- // for Gemini, so the CLI carries no per-model size table.
79
+ // ab-api maps an aspect-ratio preset to that model's pixel table, so the CLI
80
+ // carries no per-model size table.
81
81
  if (/^\d+x\d+$/i.test(size)) {
82
82
  const [w, h] = size.toLowerCase().split('x').map((v) => parseInt(v, 10));
83
83
  payload.width = w;
@@ -86,7 +86,6 @@ export async function genImage(input, ctxIn) {
86
86
  else {
87
87
  payload.aspectRatio = size;
88
88
  }
89
- payload.size = resolution;
90
89
  const ctx = await resolveHttpContext(ctxIn.skillName, {
91
90
  apiBaseUrl,
92
91
  privateToken: input.priv_token,
@@ -11,7 +11,9 @@
11
11
  * server-side, so an unknown value still passes through to the backend.
12
12
  *
13
13
  * Local image paths for first/last/reference frames are read and base64-encoded
14
- * into a data: URI; https / data: URIs pass through unchanged.
14
+ * into a data: URI; https / data: URIs pass through unchanged. Reference videos
15
+ * and audio are the exception — they must already be public URLs, see
16
+ * `requirePublicUrls`.
15
17
  */
16
18
  import type { HandlerContext, HandlerInput } from './index.js';
17
19
  export declare function genVideo(input: HandlerInput, ctxIn: HandlerContext): Promise<void>;
@@ -11,14 +11,16 @@
11
11
  * server-side, so an unknown value still passes through to the backend.
12
12
  *
13
13
  * Local image paths for first/last/reference frames are read and base64-encoded
14
- * into a data: URI; https / data: URIs pass through unchanged.
14
+ * into a data: URI; https / data: URIs pass through unchanged. Reference videos
15
+ * and audio are the exception — they must already be public URLs, see
16
+ * `requirePublicUrls`.
15
17
  */
16
18
  import { mmPost, pollUntil, resolveHttpContext, SkillError } from '../http.js';
17
19
  import { getCapabilities, matchModel, defaultModel } from '../capabilities.js';
18
20
  import { emitProgress } from '../progress.js';
19
21
  import { isTrue, resolveImageInput, toNumber, toStringArray } from './shared.js';
20
22
  /** Generic, catalog-driven validation. No model names live here. */
21
- function validateAgainstConstraints(descriptor, duration, ratio, resolution, refCount) {
23
+ function validateAgainstConstraints(descriptor, duration, ratio, resolution, refs) {
22
24
  const c = descriptor.constraints;
23
25
  const label = descriptor.label || descriptor.id;
24
26
  if (c.durations && c.durations.length > 0) {
@@ -37,12 +39,35 @@ function validateAgainstConstraints(descriptor, duration, ratio, resolution, ref
37
39
  if (c.resolutions && c.resolutions.length > 0 && !c.resolutions.includes(resolution)) {
38
40
  throw new SkillError(`❌ ${label} resolution must be one of: ${c.resolutions.join(', ')}; got: ${resolution}`);
39
41
  }
40
- if (c.refImageMax !== undefined && refCount > c.refImageMax) {
42
+ if (c.refImageMax !== undefined && refs.images > c.refImageMax) {
41
43
  if (c.refImageMax === 0) {
42
44
  throw new SkillError(`❌ ${label} does not support a reference-image array; use --first-frame / --last-frame instead`);
43
45
  }
44
- throw new SkillError(`❌ ${label} accepts at most ${c.refImageMax} reference images; got: ${refCount}`);
46
+ throw new SkillError(`❌ ${label} accepts at most ${c.refImageMax} reference images; got: ${refs.images}`);
45
47
  }
48
+ if (c.refVideoMax !== undefined && refs.videos > c.refVideoMax) {
49
+ throw new SkillError(`❌ ${label} accepts at most ${c.refVideoMax} reference videos; got: ${refs.videos}`);
50
+ }
51
+ if (c.refAudioMax !== undefined && refs.audios > c.refAudioMax) {
52
+ throw new SkillError(`❌ ${label} accepts at most ${c.refAudioMax} reference audio clips; got: ${refs.audios}`);
53
+ }
54
+ }
55
+ /**
56
+ * Reference videos / audio must be public https URLs.
57
+ *
58
+ * Unlike images, they are NOT inlined as data URIs: the caps are 50 MB per video
59
+ * and 15 MB per clip, and base64 inflates that by a third before it ever reaches
60
+ * the gateway. Failing here with the offending path beats a truncated upload or
61
+ * an opaque 413 three hops downstream.
62
+ */
63
+ function requirePublicUrls(values, flag) {
64
+ return values.map((value) => {
65
+ const url = value.trim();
66
+ if (!/^https?:\/\//i.test(url)) {
67
+ throw new SkillError(`❌ ${flag} needs a public http(s) URL (local files are not uploaded), received: ${value}`);
68
+ }
69
+ return url;
70
+ });
46
71
  }
47
72
  async function pollVideoStatus(ctx, taskId) {
48
73
  return pollUntil(async () => {
@@ -69,10 +94,26 @@ export async function genVideo(input, ctxIn) {
69
94
  const firstFrame = input.first_frame ? resolveImageInput(String(input.first_frame)) : '';
70
95
  const lastFrame = input.last_frame ? resolveImageInput(String(input.last_frame)) : '';
71
96
  const references = toStringArray(input.reference).map(resolveImageInput).filter(Boolean);
97
+ const referenceVideos = requirePublicUrls(toStringArray(input.reference_video).filter(Boolean), '--reference-video');
98
+ const referenceAudios = requirePublicUrls(toStringArray(input.reference_audio).filter(Boolean), '--reference-audio');
72
99
  const prompt = (input.prompt ?? '').trim();
73
- const hasVisual = Boolean(firstFrame || lastFrame || references.length > 0);
100
+ const hasVisual = Boolean(firstFrame || lastFrame || references.length > 0 || referenceVideos.length > 0);
74
101
  if (!prompt && !hasVisual) {
75
- throw new SkillError('❌ Provide at least one of: a non-empty --prompt, or --first-frame / --last-frame / --reference');
102
+ throw new SkillError('❌ Provide at least one of: a non-empty --prompt, or --first-frame / --last-frame / --reference / --reference-video');
103
+ }
104
+ /**
105
+ * Two shapes the backend rejects outright; catching them here saves a round
106
+ * trip and names the flag that caused it.
107
+ *
108
+ * - first/last frame pins exact frames, omni-modal reference lets the model
109
+ * re-cut — the API has no meaning for both at once;
110
+ * - audio-only (or text + audio) input is not a supported modality mix.
111
+ */
112
+ if ((firstFrame || lastFrame) && (referenceVideos.length > 0 || referenceAudios.length > 0)) {
113
+ throw new SkillError('❌ --reference-video / --reference-audio cannot be combined with --first-frame / --last-frame; use --reference for images instead');
114
+ }
115
+ if (referenceAudios.length > 0 && references.length === 0 && referenceVideos.length === 0) {
116
+ throw new SkillError('❌ --reference-audio needs at least one --reference image or --reference-video alongside it');
76
117
  }
77
118
  const ratio = input.ratio ?? '16:9';
78
119
  const resolution = input.resolution ?? '720p';
@@ -80,7 +121,11 @@ export async function genVideo(input, ctxIn) {
80
121
  const seed = toNumber(input.seed, 'seed');
81
122
  // Pre-flight validation only when we recognize the model (have its constraints).
82
123
  if (descriptor) {
83
- validateAgainstConstraints(descriptor, duration, ratio, resolution, references.length);
124
+ validateAgainstConstraints(descriptor, duration, ratio, resolution, {
125
+ images: references.length,
126
+ videos: referenceVideos.length,
127
+ audios: referenceAudios.length,
128
+ });
84
129
  }
85
130
  const ctx = await resolveHttpContext(ctxIn.skillName, {
86
131
  apiBaseUrl,
@@ -103,6 +148,16 @@ export async function genVideo(input, ctxIn) {
103
148
  payload.lastFrameImage = lastFrame;
104
149
  if (references.length > 0)
105
150
  payload.referenceImages = references;
151
+ if (referenceVideos.length > 0)
152
+ payload.referenceVideos = referenceVideos;
153
+ if (referenceAudios.length > 0)
154
+ payload.referenceAudios = referenceAudios;
155
+ // Web search only fires on text-only input; sending it alongside attachments
156
+ // would be a knob the model silently ignores.
157
+ if (isTrue(input.web_search) && !hasVisual)
158
+ payload.webSearch = true;
159
+ if (isTrue(input.return_last_frame))
160
+ payload.returnLastFrame = true;
106
161
  if (input.negative_prompt && String(input.negative_prompt).trim()) {
107
162
  payload.negativePrompt = String(input.negative_prompt).trim();
108
163
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "0.9.19",
4
- "generatedAt": "2026-09-02T05:46:15.901Z",
3
+ "version": "0.9.21",
4
+ "generatedAt": "2026-09-05T08:18:35.420Z",
5
5
  "skills": [
6
6
  {
7
7
  "id": "export-jianying",
@@ -217,11 +217,11 @@
217
217
  "tier": "atomic",
218
218
  "category": "asset",
219
219
  "title": "AI Image Generation",
220
- "summary": "AI image generation: produce an image from a text prompt. Supports the Seedream family (including a high-fidelity 'pro' variant) and Gemini, plus image-to-image with reference images.",
220
+ "summary": "AI image generation: produce an image from a text prompt. Supports the Seedream 5.0 family (Lite and a high-fidelity 'pro' variant), plus image-to-image with reference images.",
221
221
  "triggers": [
222
222
  "AI image generation, text-to-image, \"draw me ...\", \"generate an image of ...\"",
223
223
  "Image-to-image, reference image, style transfer, image variation",
224
- "Generate an image with Doubao / Seedream / Gemini",
224
+ "Generate an image with Doubao / Seedream",
225
225
  "Provide a prompt and ask for an image"
226
226
  ],
227
227
  "entry": {
@@ -244,7 +244,7 @@
244
244
  },
245
245
  "model": {
246
246
  "type": "string",
247
- "description": "Model: 'seedream' (default), 'seedream-pro' (high fidelity, precise placement and on-image text; costs more per image), or 'gemini'"
247
+ "description": "Model: 'seedream' (default, Seedream 5.0 Lite) or 'seedream-pro' (high fidelity, precise placement and on-image text; costs more per image)"
248
248
  },
249
249
  "size": {
250
250
  "type": "string",
@@ -257,7 +257,7 @@
257
257
  "2K",
258
258
  "4K"
259
259
  ],
260
- "description": "Output resolution (Gemini only)"
260
+ "description": "Output resolution tier. Currently inert: the only backend model that read it (Gemini) is not wired up, so this is ignored — use `size` for image dimensions."
261
261
  },
262
262
  "n": {
263
263
  "type": "number",
@@ -268,7 +268,7 @@
268
268
  "items": {
269
269
  "type": "string"
270
270
  },
271
- "description": "Reference images for image-to-image: local file path, https URL, or data URI. Pass multiple to blend several references (seedream: max 14, seedream-pro: max 10, gemini: max 4 — over the limit fails before spending credits)."
271
+ "description": "Reference images for image-to-image: local file path, https URL, or data URI. Pass multiple to blend several references (seedream: max 14, seedream-pro: max 10 — over the limit fails before spending credits)."
272
272
  },
273
273
  "image_strength": {
274
274
  "type": "number",
@@ -302,21 +302,21 @@
302
302
  "ui": {
303
303
  "primary": [
304
304
  "prompt",
305
+ "reference",
305
306
  "model",
306
- "size"
307
+ "size",
308
+ "n"
307
309
  ],
308
310
  "advanced": [
309
- "n",
310
- "reference",
311
- "negative_prompt",
312
- "resolution",
313
- "image_strength"
311
+ "negative_prompt"
314
312
  ],
315
313
  "hidden": [
316
314
  "json_output",
315
+ "watermark",
316
+ "resolution",
317
317
  "seed",
318
318
  "guidance_scale",
319
- "watermark"
319
+ "image_strength"
320
320
  ]
321
321
  }
322
322
  },
@@ -406,7 +406,7 @@
406
406
  "items": {
407
407
  "type": "string"
408
408
  },
409
- "description": "Bottom typewriter text lines for templates that support a caption/typewriter area (e.g. spotlight-card). Each element is one line of text. Supports **emphasis** syntax (rendered with accent color). **Must** pass when the user explicitly provides bullet-point text / bottom copy for the video."
409
+ "description": "Bottom typewriter text lines for templates that support a caption/typewriter area (e.g. spotlight-card). Each element is one line of text, max 10 lines. Supports **emphasis** syntax (rendered with accent color). **Must** pass when the user explicitly provides bullet-point text / bottom copy. **Also must pass — written by you — when the user did NOT provide any copy but the template is typewriter-driven** (capabilities.durationStrategy=fit-caption, e.g. spotlight-card): such templates have no narration, so these lines are both the video's content and the thing that decides its duration. Draft them from the material you researched (repo README, page screenshots, the topic). Leaving this empty for a fit-caption template is rejected: nothing auto-generates caption text, and an empty caption renders a titled carousel with no words at all."
410
410
  },
411
411
  "stub_image_url": {
412
412
  "type": "string",
@@ -427,11 +427,12 @@
427
427
  },
428
428
  "ui": {
429
429
  "primary": [
430
- "topic",
431
- "platform",
432
- "duration"
430
+ "topic"
433
431
  ],
434
- "advanced": [
432
+ "advanced": [],
433
+ "hidden": [
434
+ "platform",
435
+ "duration",
435
436
  "style",
436
437
  "ratio",
437
438
  "scenes",
@@ -440,9 +441,7 @@
440
441
  "headline",
441
442
  "subheadline",
442
443
  "carousel_items",
443
- "caption_lines"
444
- ],
445
- "hidden": [
444
+ "caption_lines",
446
445
  "stub_image_url",
447
446
  "stub_video_url",
448
447
  "skip_asset_generation"
@@ -455,11 +454,12 @@
455
454
  "tier": "atomic",
456
455
  "category": "asset",
457
456
  "title": "AI Video Generation",
458
- "summary": "AI video generation: produce a short video clip from a text prompt. Supports Seedance and Veo models, plus first/last frame and reference images.",
457
+ "summary": "AI video generation: produce a short video clip from a text prompt. Three Seedance 2.0 tiers (mini / fast / standard), plus first/last frame and reference images.",
459
458
  "triggers": [
460
459
  "Text-to-video, AI-generated clip, \"make a short video of ...\"",
461
- "Generate video with Doubao / Seedance / Veo / Google",
462
- "Image-to-video, first-frame / last-frame, reference-image-to-video"
460
+ "Generate video with Doubao / Seedance",
461
+ "Image-to-video, first-frame / last-frame, reference-image-to-video",
462
+ "Reference video / reference audio, \"same camera move as this clip\", \"use this track\""
463
463
  ],
464
464
  "entry": {
465
465
  "type": "http",
@@ -481,7 +481,7 @@
481
481
  },
482
482
  "model": {
483
483
  "type": "string",
484
- "description": "Model: 'seedance' (default; 4-12s, adaptive/21:9 ratios, fixed camera), 'veo' (4/6/8s, native audio, up to 4k, reference images), or 'veo-fast' (faster Veo variant for iteration)"
484
+ "description": "Model: 'seedance-mini' (default; cheapest, 480p/720p), 'seedance-fast' (480p/720p), or 'seedance' (Seedance 2.0, adds 1080p). All are 4-15s and share the same features"
485
485
  },
486
486
  "duration": {
487
487
  "type": "number",
@@ -508,7 +508,29 @@
508
508
  "items": {
509
509
  "type": "string"
510
510
  },
511
- "description": "Reference images: local file path, https URL, or data URI. Veo only, max 3 Seedance rejects them, use first_frame / last_frame instead."
511
+ "description": "Reference images: local file path, https URL, or data URI. Up to 9; combinable with first_frame / last_frame."
512
+ },
513
+ "reference_video": {
514
+ "type": "array",
515
+ "items": {
516
+ "type": "string"
517
+ },
518
+ "description": "Reference videos (https URL only, must be publicly reachable). Up to 3. The model borrows their subject, camera work and style. Cannot be combined with first_frame / last_frame."
519
+ },
520
+ "reference_audio": {
521
+ "type": "array",
522
+ "items": {
523
+ "type": "string"
524
+ },
525
+ "description": "Reference audio (https URL only, must be publicly reachable). Up to 3. Borrows timbre, melody or dialogue. Needs at least one reference image or video alongside it; cannot be combined with first_frame / last_frame."
526
+ },
527
+ "web_search": {
528
+ "type": "boolean",
529
+ "description": "Let the model search the web for up-to-date subjects before generating. Text-only input — ignored once any image / video / audio is attached."
530
+ },
531
+ "return_last_frame": {
532
+ "type": "boolean",
533
+ "description": "Also return the generated clip's last frame, to chain it into the next shot"
512
534
  },
513
535
  "generate_audio": {
514
536
  "type": "boolean",
@@ -520,11 +542,11 @@
520
542
  },
521
543
  "negative_prompt": {
522
544
  "type": "string",
523
- "description": "Content to steer away from (Veo)"
545
+ "description": "Content to steer away from. Veo only — Seedance ignores it (kept for when a Veo channel is available again)"
524
546
  },
525
547
  "seed": {
526
548
  "type": "number",
527
- "description": "Random seed. Pass the same seed with the same prompt and model to make a run reproducible."
549
+ "description": "Random seed, -1 for random. Pass the same seed with the same prompt and model to make a run reproducible."
528
550
  },
529
551
  "person_generation": {
530
552
  "type": "string",
@@ -548,20 +570,24 @@
548
570
  "prompt",
549
571
  "model",
550
572
  "duration",
551
- "ratio"
573
+ "ratio",
574
+ "resolution"
552
575
  ],
553
576
  "advanced": [
554
- "resolution",
555
577
  "first_frame",
556
578
  "last_frame",
557
579
  "reference",
580
+ "reference_video",
581
+ "reference_audio",
558
582
  "generate_audio",
559
583
  "camera_fixed",
560
- "negative_prompt"
584
+ "web_search",
585
+ "return_last_frame",
586
+ "seed"
561
587
  ],
562
588
  "hidden": [
563
589
  "json_output",
564
- "seed",
590
+ "negative_prompt",
565
591
  "person_generation"
566
592
  ]
567
593
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remixmate/cli",
3
- "version": "0.9.19",
3
+ "version": "0.9.21",
4
4
  "description": "AI media generation skills for Claude Code / Codex — 12 skills covering image, video, voice, digital human, web screenshot, web recording, script, template registry, rendering, Jianying export, and video deconstruction.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,25 +1,25 @@
1
1
  ---
2
2
  name: gen-image
3
3
  description: |
4
- AI image generation skill: produce an image from a text prompt, or do image-to-image with reference images. Backed by ab-api's `/model/genImg` (Seedream and Gemini families).
4
+ AI image generation skill: produce an image from a text prompt, or do image-to-image with reference images. Backed by ab-api's `/model/genImg` (the Seedream 5.0 family).
5
5
 
6
6
  Use this skill immediately whenever the user asks for any of:
7
7
  - AI image generation, text-to-image, "draw me ...", "generate an image of ..."
8
8
  - Image-to-image, reference image, style transfer, image variation
9
- - Generate an image with Doubao / Seedream / Gemini
9
+ - Generate an image with Doubao / Seedream
10
10
  - Provide a prompt and ask for an image
11
11
 
12
12
  Even without an explicit "use AI", any request that turns a description into an image should route here.
13
13
  triggers:
14
14
  - AI image generation, text-to-image, "draw me ...", "generate an image of ..."
15
15
  - Image-to-image, reference image, style transfer, image variation
16
- - Generate an image with Doubao / Seedream / Gemini
16
+ - Generate an image with Doubao / Seedream
17
17
  - Provide a prompt and ask for an image
18
18
  ---
19
19
 
20
20
  # AI Image Generation Skill
21
21
 
22
- Wraps ab-api's `POST /model/genImg` (the same endpoint the web studio uses), authenticated with the **Tianyan privateToken**, routed through LiteLLM to **Seedream** or **Gemini**.
22
+ Wraps ab-api's `POST /model/genImg` (the same endpoint the web studio uses), authenticated with the **Tianyan privateToken**, routed through LiteLLM to the **Seedream 5.0** family.
23
23
 
24
24
  ## Models and sizes
25
25
 
@@ -31,7 +31,6 @@ the names below are the stable aliases to use.
31
31
  |-----------|------------|------------------|
32
32
  | `seedream` | Default. General-purpose, highest output resolution. | up to 14 |
33
33
  | `seedream-pro` | High-fidelity variant: better placement/element control, more faithful text rendering. Costs more per image. | up to 10 |
34
- | `gemini` | Gemini 3 Pro. | up to 4 |
35
34
 
36
35
  - **Seedream**: `--size` is an aspect ratio (e.g. `1:1`, `9:16`) or `WxH`. The backend maps the
37
36
  ratio to that model's own pixel preset and rescales out-of-range sizes, so prefer a ratio
@@ -39,8 +38,8 @@ the names below are the stable aliases to use.
39
38
  - **`seedream-pro`** additionally supports `3:2` / `2:3` / `21:9`, and caps output at ~2K
40
39
  (about 4.6 MP). Asking it for 4K pixels gets scaled down, not rejected — use `seedream`
41
40
  when you need a genuinely larger image.
42
- - **Gemini**: `--size` is a backend-allowed aspect ratio (e.g. `1:1`, `16:9`); add
43
- `--resolution`: `1K` / `2K` / `4K` (default `1K`). `--resolution` is ignored by Seedream.
41
+ - **`--resolution`** is inert today: it only ever applied to Gemini, which is not wired up on
42
+ the gateway. Control image dimensions with `--size`.
44
43
 
45
44
  ## Auth & environment
46
45
 
@@ -71,14 +70,6 @@ remixmate gen-image \
71
70
  --size "9:16"
72
71
  ```
73
72
 
74
- ```bash
75
- remixmate gen-image \
76
- --prompt "<image description>" \
77
- --model gemini \
78
- --size "16:9" \
79
- --resolution "2K"
80
- ```
81
-
82
73
  ```bash
83
74
  # High-fidelity: precise placement, legible on-image text
84
75
  remixmate gen-image \
@@ -95,7 +86,6 @@ Reference images accept local file paths, HTTPS URLs, or data URIs. Pass `--refe
95
86
  - **`seedream-pro`**: up to **10** reference images. Best choice when the edit has to land in a
96
87
  specific spot — describe the target region in the prompt (e.g. "in the marked area at the
97
88
  bottom left") and it holds position far better than `seedream`.
98
- - **`gemini`**: up to **4** reference images.
99
89
 
100
90
  Over-the-limit runs fail fast in the CLI, before spending credits.
101
91
 
@@ -129,13 +119,12 @@ remixmate gen-image \
129
119
  | Flag | Description | Default |
130
120
  |------|-------------|---------|
131
121
  | `-p` / `--prompt` | Description (required) | — |
132
- | `-m` / `--model` | `seedream` / `seedream-pro` / `gemini` | see `MM_IMAGE_MODEL` |
133
- | `-s` / `--size` | Seedream: ratio or WxH; Gemini: ratio | `1:1` |
134
- | `--resolution` | Gemini only: `1K` / `2K` / `4K` | `1K` |
122
+ | `-m` / `--model` | `seedream` / `seedream-pro` | see `MM_IMAGE_MODEL` |
123
+ | `-s` / `--size` | Aspect ratio or WxH | `1:1` |
135
124
  | `-n` | Number of images, 1–4 | `1` |
136
125
  | `-g` / `--guidance-scale` | Guidance scale (when supported) | backend default |
137
126
  | `--reference` | Reference image (repeatable; local path / URL / data URI) | none |
138
- | `--image-strength` | Reference strength 0–1 (Seedream only) | backend default |
127
+ | `--image-strength` | Reference strength 0–1 | backend default |
139
128
  | `--negative-prompt` | Things to avoid | none |
140
129
  | `--seed` | Random seed (reproducibility) | none |
141
130
  | `--watermark` | Add a watermark (no `--no-watermark` opt-out) | backend default |
@@ -4,7 +4,7 @@
4
4
  "tier": "atomic",
5
5
  "category": "asset",
6
6
  "title": "AI Image Generation",
7
- "description": "AI image generation: produce an image from a text prompt. Supports the Seedream family (including a high-fidelity 'pro' variant) and Gemini, plus image-to-image with reference images.",
7
+ "description": "AI image generation: produce an image from a text prompt. Supports the Seedream 5.0 family (Lite and a high-fidelity 'pro' variant), plus image-to-image with reference images.",
8
8
  "auth": "required",
9
9
  "joinsTake": true,
10
10
  "envVars": [
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "model": {
28
28
  "type": "string",
29
- "description": "Model: 'seedream' (default), 'seedream-pro' (high fidelity, precise placement and on-image text; costs more per image), or 'gemini'"
29
+ "description": "Model: 'seedream' (default, Seedream 5.0 Lite) or 'seedream-pro' (high fidelity, precise placement and on-image text; costs more per image)"
30
30
  },
31
31
  "size": {
32
32
  "type": "string",
@@ -39,7 +39,7 @@
39
39
  "2K",
40
40
  "4K"
41
41
  ],
42
- "description": "Output resolution (Gemini only)"
42
+ "description": "Output resolution tier. Currently inert: the only backend model that read it (Gemini) is not wired up, so this is ignored — use `size` for image dimensions."
43
43
  },
44
44
  "n": {
45
45
  "type": "number",
@@ -50,7 +50,7 @@
50
50
  "items": {
51
51
  "type": "string"
52
52
  },
53
- "description": "Reference images for image-to-image: local file path, https URL, or data URI. Pass multiple to blend several references (seedream: max 14, seedream-pro: max 10, gemini: max 4 — over the limit fails before spending credits)."
53
+ "description": "Reference images for image-to-image: local file path, https URL, or data URI. Pass multiple to blend several references (seedream: max 14, seedream-pro: max 10 — over the limit fails before spending credits)."
54
54
  },
55
55
  "image_strength": {
56
56
  "type": "number",
@@ -84,21 +84,21 @@
84
84
  "ui": {
85
85
  "primary": [
86
86
  "prompt",
87
+ "reference",
87
88
  "model",
88
- "size"
89
+ "size",
90
+ "n"
89
91
  ],
90
92
  "advanced": [
91
- "n",
92
- "reference",
93
- "negative_prompt",
94
- "resolution",
95
- "image_strength"
93
+ "negative_prompt"
96
94
  ],
97
95
  "hidden": [
98
96
  "json_output",
97
+ "watermark",
98
+ "resolution",
99
99
  "seed",
100
100
  "guidance_scale",
101
- "watermark"
101
+ "image_strength"
102
102
  ]
103
103
  }
104
104
  }
@@ -2,6 +2,6 @@
2
2
  "skillName": "gen-image",
3
3
  "repoName": "agent-skill-media-maker",
4
4
  "skillId": "337",
5
- "version": "V9",
6
- "skillDescription": "AI image generation skill: produce an image from a text prompt, or do image-to-image with reference images. Backed by ab-api's `/model/genImg` (Seedream and Gemini families).\n\nUse this skill immediately whenever the user asks for any of:\n- AI image generation, text-to-image, \"draw me ...\", \"generate an image of ...\"\n- Image-to-image, reference image, style transfer, image variation\n- Generate an image with Doubao / Seedream / Gemini\n- Provide a prompt and ask for an image\n\nEven without an explicit \"use AI\", any request that turns a description into an image should route here."
5
+ "version": "V10",
6
+ "skillDescription": "AI image generation skill: produce an image from a text prompt, or do image-to-image with reference images. Backed by ab-api's `/model/genImg` (the Seedream 5.0 family).\n\nUse this skill immediately whenever the user asks for any of:\n- AI image generation, text-to-image, \"draw me ...\", \"generate an image of ...\"\n- Image-to-image, reference image, style transfer, image variation\n- Generate an image with Doubao / Seedream\n- Provide a prompt and ask for an image\n\nEven without an explicit \"use AI\", any request that turns a description into an image should route here."
7
7
  }