everypixel-cli 0.1.0__tar.gz → 0.2.1__tar.gz
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.
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/CHANGELOG.md +11 -0
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/PKG-INFO +51 -1
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/README.md +50 -0
- everypixel_cli-0.2.1/src/everypixel_cli/__init__.py +1 -0
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/application/services.py +136 -28
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/cli.py +69 -11
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/mcp_server.py +35 -5
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/resources/openapi.json +662 -109
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/schemas.py +268 -75
- everypixel_cli-0.1.0/src/everypixel_cli/__init__.py +0 -1
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/.gitignore +0 -0
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/LICENSE +0 -0
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/pyproject.toml +0 -0
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/__main__.py +0 -0
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/application/__init__.py +0 -0
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/application/models.py +0 -0
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/application/serialization.py +0 -0
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/client.py +0 -0
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/config.py +0 -0
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/errors.py +0 -0
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/files.py +0 -0
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/openapi.py +0 -0
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/output.py +0 -0
- {everypixel_cli-0.1.0 → everypixel_cli-0.2.1}/src/everypixel_cli/resources/__init__.py +0 -0
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.1] - 2026-09-11
|
|
4
|
+
|
|
5
|
+
- Support up to 9 image, 3 video, and 3 audio references for MiniMax H3/Turbo.
|
|
6
|
+
|
|
7
|
+
## [0.2.0] - 2026-09-09
|
|
8
|
+
|
|
9
|
+
- Add MiniMax H3/Turbo, WAN 3.0, Flux 3, and Seedance 2.5 video models.
|
|
10
|
+
- Add Recraft vector generation, palette controls, and image-to-SVG conversion.
|
|
11
|
+
- Update Grok Imagine models, image-edit input limits, and megapixel controls.
|
|
12
|
+
- Add Topaz 4K video upscaling and 720p lipsync.
|
|
13
|
+
|
|
3
14
|
## [0.1.0] - 2026-08-17
|
|
4
15
|
|
|
5
16
|
Initial public release.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: everypixel-cli
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Official command line interface for Everypixel API
|
|
5
5
|
Project-URL: Homepage, https://labs.everypixel.com
|
|
6
6
|
Project-URL: Repository, https://github.com/everypixel/everypixel-cli
|
|
@@ -144,6 +144,7 @@ CLI falls back to its user configuration file when a keyring is unavailable;
|
|
|
144
144
|
| --- | --- |
|
|
145
145
|
| `everypixel image generate PROMPT` | Generate an image from a text prompt |
|
|
146
146
|
| `everypixel image edit PROMPT --image FILE` | Edit one or more images |
|
|
147
|
+
| `everypixel image vectorize FILE` | Convert an image to SVG |
|
|
147
148
|
| `everypixel image upscale` | Upscale an image, URL, or existing task result |
|
|
148
149
|
| `everypixel image angles --image FILE` | Change the camera angle of an image |
|
|
149
150
|
| `everypixel image colors --image FILE --reference FILE` | Transfer colors from a reference image |
|
|
@@ -159,6 +160,13 @@ everypixel image edit \
|
|
|
159
160
|
|
|
160
161
|
everypixel image upscale --image ./input.png --download ./outputs
|
|
161
162
|
|
|
163
|
+
everypixel image generate "a mountain icon" \
|
|
164
|
+
--model recraftv4_1_vector \
|
|
165
|
+
--controls '{"colors":[{"rgb":[20,100,180],"weight":1}]}' \
|
|
166
|
+
--download ./outputs
|
|
167
|
+
|
|
168
|
+
everypixel image vectorize ./input.png --download ./outputs
|
|
169
|
+
|
|
162
170
|
everypixel image angles \
|
|
163
171
|
--image ./input.png \
|
|
164
172
|
--azimuth right \
|
|
@@ -167,6 +175,16 @@ everypixel image angles \
|
|
|
167
175
|
--download ./outputs
|
|
168
176
|
```
|
|
169
177
|
|
|
178
|
+
Recraft V4.1 vector models (`recraftv4_1_vector`, `recraftv4_1_pro_vector`)
|
|
179
|
+
produce SVG files and accept optional JSON palette `--controls`. Use `--size`
|
|
180
|
+
to select their aspect ratio. Raster models also accept `--resolution`.
|
|
181
|
+
|
|
182
|
+
`--lora-url` is supported only by `zimage`.
|
|
183
|
+
|
|
184
|
+
Grok image models are `grok-imagine`, `grok-imagine-2`, and
|
|
185
|
+
`grok-imagine-2-low`. The `grok` alias remains supported. `grok_quality` and
|
|
186
|
+
`wan22` have been removed from the API.
|
|
187
|
+
|
|
170
188
|
### Video
|
|
171
189
|
|
|
172
190
|
| Command | Description |
|
|
@@ -197,8 +215,38 @@ everypixel video edit \
|
|
|
197
215
|
"make the scene cinematic" \
|
|
198
216
|
--video ./input.mp4 \
|
|
199
217
|
--download ./outputs
|
|
218
|
+
|
|
219
|
+
everypixel video generate "a slow aerial shot over mountain lakes" \
|
|
220
|
+
--model minimax-h3-turbo --duration 10 --download ./outputs
|
|
221
|
+
|
|
222
|
+
everypixel video edit "continue the scene with a slow camera pan" \
|
|
223
|
+
--model flux3 --video ./input.mp4 --download ./outputs
|
|
224
|
+
|
|
225
|
+
everypixel video upscale --video ./input.mp4 \
|
|
226
|
+
--model topaz-prob-4 --resolution 4k --download ./outputs
|
|
200
227
|
```
|
|
201
228
|
|
|
229
|
+
New video models use these provider defaults and limits:
|
|
230
|
+
|
|
231
|
+
| Model | Duration | Default resolution / aspect ratio | Inputs |
|
|
232
|
+
| --- | --- | --- | --- |
|
|
233
|
+
| `minimax-h3-turbo`, `minimax-h3` | 3–15 s | 768p / 7:4 | Text, first/last frames, or up to 9 image, 3 video, and 3 audio references |
|
|
234
|
+
| `wan3.0` | 2–30 s | 1080p / adaptive | Text, frames, or up to 10 reference images and 5 reference videos |
|
|
235
|
+
| `flux3` | 5–20 s generation; 5–15 s continuation | 720p / 16:9 | Text, frames, or `video edit --video` for continuation |
|
|
236
|
+
| `seedance2.5` | 4–30 s | 720p / 16:9 | Text or `video edit` references, including audio alone |
|
|
237
|
+
|
|
238
|
+
Use repeatable `--reference-image`, `--reference-video`, and `--reference-audio`
|
|
239
|
+
options for MiniMax references. References cannot be combined with first/last
|
|
240
|
+
frames. WAN 3.0 also separates frame and reference inputs. Seedance 2.5 supports
|
|
241
|
+
up to 1080p;
|
|
242
|
+
Seedance 2 and Mini retain their 15-second limit. Grok video model names are
|
|
243
|
+
`grok-imagine` and `grok-imagine-1.5` (image required); `grok` and `grok15`
|
|
244
|
+
remain accepted aliases. The CLI's default video model remains `ltx23`.
|
|
245
|
+
|
|
246
|
+
Topaz upscaling models are `topaz-prob-4`, `topaz-slp-2.5`, and `topaz-ast-2`.
|
|
247
|
+
They support 4K output. The default `seedvr2` supports up to 1440p, with a
|
|
248
|
+
20-second source limit at 1080p and a 10-second limit at 1440p, inclusive.
|
|
249
|
+
|
|
202
250
|
### Lipsync and Audio
|
|
203
251
|
|
|
204
252
|
| Command | Description |
|
|
@@ -210,6 +258,8 @@ everypixel video edit \
|
|
|
210
258
|
| `everypixel audio tts-clone` | Create speech from a cloned voice sample |
|
|
211
259
|
| `everypixel audio tts-voice` | Create speech with a character voice |
|
|
212
260
|
|
|
261
|
+
Lipsync supports 720p; the API checks source media dimensions and duration.
|
|
262
|
+
|
|
213
263
|
Examples:
|
|
214
264
|
|
|
215
265
|
```bash
|
|
@@ -110,6 +110,7 @@ CLI falls back to its user configuration file when a keyring is unavailable;
|
|
|
110
110
|
| --- | --- |
|
|
111
111
|
| `everypixel image generate PROMPT` | Generate an image from a text prompt |
|
|
112
112
|
| `everypixel image edit PROMPT --image FILE` | Edit one or more images |
|
|
113
|
+
| `everypixel image vectorize FILE` | Convert an image to SVG |
|
|
113
114
|
| `everypixel image upscale` | Upscale an image, URL, or existing task result |
|
|
114
115
|
| `everypixel image angles --image FILE` | Change the camera angle of an image |
|
|
115
116
|
| `everypixel image colors --image FILE --reference FILE` | Transfer colors from a reference image |
|
|
@@ -125,6 +126,13 @@ everypixel image edit \
|
|
|
125
126
|
|
|
126
127
|
everypixel image upscale --image ./input.png --download ./outputs
|
|
127
128
|
|
|
129
|
+
everypixel image generate "a mountain icon" \
|
|
130
|
+
--model recraftv4_1_vector \
|
|
131
|
+
--controls '{"colors":[{"rgb":[20,100,180],"weight":1}]}' \
|
|
132
|
+
--download ./outputs
|
|
133
|
+
|
|
134
|
+
everypixel image vectorize ./input.png --download ./outputs
|
|
135
|
+
|
|
128
136
|
everypixel image angles \
|
|
129
137
|
--image ./input.png \
|
|
130
138
|
--azimuth right \
|
|
@@ -133,6 +141,16 @@ everypixel image angles \
|
|
|
133
141
|
--download ./outputs
|
|
134
142
|
```
|
|
135
143
|
|
|
144
|
+
Recraft V4.1 vector models (`recraftv4_1_vector`, `recraftv4_1_pro_vector`)
|
|
145
|
+
produce SVG files and accept optional JSON palette `--controls`. Use `--size`
|
|
146
|
+
to select their aspect ratio. Raster models also accept `--resolution`.
|
|
147
|
+
|
|
148
|
+
`--lora-url` is supported only by `zimage`.
|
|
149
|
+
|
|
150
|
+
Grok image models are `grok-imagine`, `grok-imagine-2`, and
|
|
151
|
+
`grok-imagine-2-low`. The `grok` alias remains supported. `grok_quality` and
|
|
152
|
+
`wan22` have been removed from the API.
|
|
153
|
+
|
|
136
154
|
### Video
|
|
137
155
|
|
|
138
156
|
| Command | Description |
|
|
@@ -163,8 +181,38 @@ everypixel video edit \
|
|
|
163
181
|
"make the scene cinematic" \
|
|
164
182
|
--video ./input.mp4 \
|
|
165
183
|
--download ./outputs
|
|
184
|
+
|
|
185
|
+
everypixel video generate "a slow aerial shot over mountain lakes" \
|
|
186
|
+
--model minimax-h3-turbo --duration 10 --download ./outputs
|
|
187
|
+
|
|
188
|
+
everypixel video edit "continue the scene with a slow camera pan" \
|
|
189
|
+
--model flux3 --video ./input.mp4 --download ./outputs
|
|
190
|
+
|
|
191
|
+
everypixel video upscale --video ./input.mp4 \
|
|
192
|
+
--model topaz-prob-4 --resolution 4k --download ./outputs
|
|
166
193
|
```
|
|
167
194
|
|
|
195
|
+
New video models use these provider defaults and limits:
|
|
196
|
+
|
|
197
|
+
| Model | Duration | Default resolution / aspect ratio | Inputs |
|
|
198
|
+
| --- | --- | --- | --- |
|
|
199
|
+
| `minimax-h3-turbo`, `minimax-h3` | 3–15 s | 768p / 7:4 | Text, first/last frames, or up to 9 image, 3 video, and 3 audio references |
|
|
200
|
+
| `wan3.0` | 2–30 s | 1080p / adaptive | Text, frames, or up to 10 reference images and 5 reference videos |
|
|
201
|
+
| `flux3` | 5–20 s generation; 5–15 s continuation | 720p / 16:9 | Text, frames, or `video edit --video` for continuation |
|
|
202
|
+
| `seedance2.5` | 4–30 s | 720p / 16:9 | Text or `video edit` references, including audio alone |
|
|
203
|
+
|
|
204
|
+
Use repeatable `--reference-image`, `--reference-video`, and `--reference-audio`
|
|
205
|
+
options for MiniMax references. References cannot be combined with first/last
|
|
206
|
+
frames. WAN 3.0 also separates frame and reference inputs. Seedance 2.5 supports
|
|
207
|
+
up to 1080p;
|
|
208
|
+
Seedance 2 and Mini retain their 15-second limit. Grok video model names are
|
|
209
|
+
`grok-imagine` and `grok-imagine-1.5` (image required); `grok` and `grok15`
|
|
210
|
+
remain accepted aliases. The CLI's default video model remains `ltx23`.
|
|
211
|
+
|
|
212
|
+
Topaz upscaling models are `topaz-prob-4`, `topaz-slp-2.5`, and `topaz-ast-2`.
|
|
213
|
+
They support 4K output. The default `seedvr2` supports up to 1440p, with a
|
|
214
|
+
20-second source limit at 1080p and a 10-second limit at 1440p, inclusive.
|
|
215
|
+
|
|
168
216
|
### Lipsync and Audio
|
|
169
217
|
|
|
170
218
|
| Command | Description |
|
|
@@ -176,6 +224,8 @@ everypixel video edit \
|
|
|
176
224
|
| `everypixel audio tts-clone` | Create speech from a cloned voice sample |
|
|
177
225
|
| `everypixel audio tts-voice` | Create speech with a character voice |
|
|
178
226
|
|
|
227
|
+
Lipsync supports 720p; the API checks source media dimensions and duration.
|
|
228
|
+
|
|
179
229
|
Examples:
|
|
180
230
|
|
|
181
231
|
```bash
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.1"
|
|
@@ -7,9 +7,9 @@ import time
|
|
|
7
7
|
from collections.abc import Callable, Mapping
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import Any, Protocol
|
|
10
|
+
from typing import Any, Protocol, get_args
|
|
11
11
|
|
|
12
|
-
from pydantic import TypeAdapter, ValidationError
|
|
12
|
+
from pydantic import BaseModel, TypeAdapter, ValidationError
|
|
13
13
|
|
|
14
14
|
from ..errors import (
|
|
15
15
|
APIResponseError,
|
|
@@ -36,12 +36,16 @@ from ..schemas import (
|
|
|
36
36
|
ImageEditPayload,
|
|
37
37
|
ImageGeneratePayload,
|
|
38
38
|
ImageUpscalePayload,
|
|
39
|
+
ImageVectorizePayload,
|
|
39
40
|
LipsyncImagePayload,
|
|
40
41
|
LipsyncVideoPayload,
|
|
42
|
+
RecraftGeneratePayload,
|
|
41
43
|
TaskResponse,
|
|
42
44
|
VideoEditRequest,
|
|
43
45
|
VideoGenerateRequest,
|
|
46
|
+
VideoGenerateModel,
|
|
44
47
|
VideoUpscalePayload,
|
|
48
|
+
normalize_grok_model,
|
|
45
49
|
)
|
|
46
50
|
from .models import (
|
|
47
51
|
ExecutionOptions,
|
|
@@ -328,6 +332,8 @@ def fallback_extension_for_endpoint(path: str) -> str:
|
|
|
328
332
|
"""Infer the existing conservative extension fallback from an endpoint path."""
|
|
329
333
|
|
|
330
334
|
lowered = path.lower()
|
|
335
|
+
if lowered == "/v1/image_vectorize":
|
|
336
|
+
return ".svg"
|
|
331
337
|
if "transcribe" in lowered or "asr" in lowered:
|
|
332
338
|
return ".txt"
|
|
333
339
|
if "video" in lowered or "lipsync" in lowered:
|
|
@@ -468,6 +474,31 @@ def _build_wan_video_edit_payload(inputs: _VideoEditInputs) -> dict[str, Any]:
|
|
|
468
474
|
)
|
|
469
475
|
|
|
470
476
|
|
|
477
|
+
def _build_flux3_video_edit_payload(inputs: _VideoEditInputs) -> dict[str, Any]:
|
|
478
|
+
_reject_video_edit_options(
|
|
479
|
+
inputs.model,
|
|
480
|
+
{
|
|
481
|
+
"image": inputs.images,
|
|
482
|
+
"audio": inputs.audio,
|
|
483
|
+
"seed": inputs.seed,
|
|
484
|
+
"keyframe": inputs.keyframes,
|
|
485
|
+
"public_figure_threshold": inputs.public_figure_threshold,
|
|
486
|
+
},
|
|
487
|
+
)
|
|
488
|
+
return _validated_video_edit_payload(
|
|
489
|
+
{
|
|
490
|
+
"prompt": inputs.prompt,
|
|
491
|
+
"model": inputs.model,
|
|
492
|
+
"duration": inputs.duration,
|
|
493
|
+
"resolution": inputs.resolution,
|
|
494
|
+
"aspect_ratio": inputs.aspect_ratio,
|
|
495
|
+
"video_url": media_value(inputs.video) if inputs.video else None,
|
|
496
|
+
"generate_audio": inputs.generate_audio,
|
|
497
|
+
"callback_url": inputs.callback_url,
|
|
498
|
+
}
|
|
499
|
+
)
|
|
500
|
+
|
|
501
|
+
|
|
471
502
|
def _parse_aleph_keyframe(value: str) -> dict[str, Any]:
|
|
472
503
|
try:
|
|
473
504
|
keyframe = json.loads(value)
|
|
@@ -509,9 +540,11 @@ def _build_aleph_video_edit_payload(inputs: _VideoEditInputs) -> dict[str, Any]:
|
|
|
509
540
|
_VIDEO_EDIT_BUILDERS: dict[str, Callable[[_VideoEditInputs], dict[str, Any]]] = {
|
|
510
541
|
"seedance2": _build_seedance_video_edit_payload,
|
|
511
542
|
"seedance2-mini": _build_seedance_video_edit_payload,
|
|
543
|
+
"seedance2.5": _build_seedance_video_edit_payload,
|
|
512
544
|
"kling-3-omni": _build_kling_video_edit_payload,
|
|
513
545
|
"wan2.7": _build_wan_video_edit_payload,
|
|
514
546
|
"aleph2": _build_aleph_video_edit_payload,
|
|
547
|
+
"flux3": _build_flux3_video_edit_payload,
|
|
515
548
|
}
|
|
516
549
|
|
|
517
550
|
|
|
@@ -557,14 +590,30 @@ def build_video_edit_payload(
|
|
|
557
590
|
return builder(inputs)
|
|
558
591
|
|
|
559
592
|
|
|
593
|
+
_IMAGE_GENERATE_BUILDERS: dict[str, type[BaseModel]] = {
|
|
594
|
+
"recraftv4_1_vector": RecraftGeneratePayload,
|
|
595
|
+
"recraftv4_1_pro_vector": RecraftGeneratePayload,
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
|
|
560
599
|
def build_image_generate_payload(**values: Any) -> dict[str, Any]:
|
|
561
600
|
"""Validate and build image generation payloads including local media."""
|
|
562
601
|
|
|
563
602
|
image = values.pop("image", None)
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
603
|
+
if image is not None:
|
|
604
|
+
values["image_url"] = media_value(image)
|
|
605
|
+
controls = values.get("controls")
|
|
606
|
+
if isinstance(controls, str):
|
|
607
|
+
try:
|
|
608
|
+
values["controls"] = json.loads(controls)
|
|
609
|
+
except json.JSONDecodeError as exc:
|
|
610
|
+
raise InputParsingError("Unable to parse Recraft controls JSON") from exc
|
|
611
|
+
builder = _IMAGE_GENERATE_BUILDERS.get(
|
|
612
|
+
values.get("model", "zimage"), ImageGeneratePayload
|
|
613
|
+
)
|
|
614
|
+
return builder.model_validate(
|
|
615
|
+
{key: value for key, value in values.items() if value is not None}
|
|
616
|
+
).model_dump(mode="json", exclude_none=True)
|
|
568
617
|
|
|
569
618
|
|
|
570
619
|
def build_image_edit_payload(**values: Any) -> dict[str, Any]:
|
|
@@ -574,7 +623,15 @@ def build_image_edit_payload(**values: Any) -> dict[str, Any]:
|
|
|
574
623
|
return ImageEditPayload(
|
|
575
624
|
**{key: value for key, value in values.items() if value is not None},
|
|
576
625
|
image_urls=[media_value(item) for item in images],
|
|
577
|
-
).model_dump(exclude_none=True)
|
|
626
|
+
).model_dump(mode="json", exclude_none=True)
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
def build_image_vectorize_payload(
|
|
630
|
+
*, image: str, callback_url: str | None
|
|
631
|
+
) -> dict[str, Any]:
|
|
632
|
+
return ImageVectorizePayload.model_validate(
|
|
633
|
+
{"image_url": media_value(image), "callback_url": callback_url}
|
|
634
|
+
).model_dump(mode="json", exclude_none=True)
|
|
578
635
|
|
|
579
636
|
|
|
580
637
|
def build_image_upscale_payload(**values: Any) -> dict[str, Any]:
|
|
@@ -594,13 +651,16 @@ def build_video_generate_payload(**values: Any) -> dict[str, Any]:
|
|
|
594
651
|
last_image = values.pop("last_image", None)
|
|
595
652
|
reference_images = values.pop("reference_images", [])
|
|
596
653
|
reference_videos = values.pop("reference_videos", [])
|
|
654
|
+
reference_audios = values.pop("reference_audios", [])
|
|
655
|
+
values = normalize_grok_model(values)
|
|
597
656
|
if values.get("duration") is None:
|
|
598
657
|
model = values.get("model")
|
|
599
658
|
required_duration_defaults = {
|
|
600
|
-
"
|
|
659
|
+
"minimax-h3-turbo": 5,
|
|
660
|
+
"minimax-h3": 5,
|
|
601
661
|
"ltx23": 5,
|
|
602
|
-
"grok": 5,
|
|
603
|
-
"
|
|
662
|
+
"grok-imagine": 5,
|
|
663
|
+
"grok-imagine-1.5": 5,
|
|
604
664
|
}
|
|
605
665
|
values["duration"] = (
|
|
606
666
|
required_duration_defaults.get(model) if isinstance(model, str) else None
|
|
@@ -618,6 +678,10 @@ def build_video_generate_payload(**values: Any) -> dict[str, Any]:
|
|
|
618
678
|
payload["reference_video_urls"] = [
|
|
619
679
|
media_value(value) for value in reference_videos
|
|
620
680
|
]
|
|
681
|
+
if reference_audios:
|
|
682
|
+
payload["reference_audio_urls"] = [
|
|
683
|
+
media_value(value) for value in reference_audios
|
|
684
|
+
]
|
|
621
685
|
validated = _VIDEO_GENERATE_ADAPTER.validate_python(
|
|
622
686
|
{key: value for key, value in payload.items() if value is not None}
|
|
623
687
|
)
|
|
@@ -771,6 +835,8 @@ class ApplicationServices:
|
|
|
771
835
|
seed: int,
|
|
772
836
|
callback_url: str | None,
|
|
773
837
|
execution: ExecutionOptions,
|
|
838
|
+
lora_url: str | None = None,
|
|
839
|
+
controls: dict[str, Any] | str | None = None,
|
|
774
840
|
) -> OperationResult:
|
|
775
841
|
payload = build_image_generate_payload(
|
|
776
842
|
prompt=prompt,
|
|
@@ -781,12 +847,33 @@ class ApplicationServices:
|
|
|
781
847
|
resolution=resolution,
|
|
782
848
|
seed=seed,
|
|
783
849
|
callback_url=callback_url,
|
|
850
|
+
lora_url=lora_url,
|
|
851
|
+
controls=controls,
|
|
784
852
|
)
|
|
785
853
|
return self._execute_async(
|
|
786
854
|
endpoint="/v1/image_generate",
|
|
787
855
|
payload=payload,
|
|
788
856
|
execution=execution,
|
|
789
|
-
fallback_extension=
|
|
857
|
+
fallback_extension=(
|
|
858
|
+
".svg" if model in _IMAGE_GENERATE_BUILDERS else ".png"
|
|
859
|
+
),
|
|
860
|
+
)
|
|
861
|
+
|
|
862
|
+
def execute_image_vectorize(
|
|
863
|
+
self,
|
|
864
|
+
*,
|
|
865
|
+
image: str,
|
|
866
|
+
callback_url: str | None = None,
|
|
867
|
+
execution: ExecutionOptions,
|
|
868
|
+
) -> OperationResult:
|
|
869
|
+
return self._execute_async(
|
|
870
|
+
endpoint="/v1/image_vectorize",
|
|
871
|
+
payload=build_image_vectorize_payload(
|
|
872
|
+
image=image,
|
|
873
|
+
callback_url=callback_url,
|
|
874
|
+
),
|
|
875
|
+
execution=execution,
|
|
876
|
+
fallback_extension=".svg",
|
|
790
877
|
)
|
|
791
878
|
|
|
792
879
|
def execute_image_edit(
|
|
@@ -800,6 +887,7 @@ class ApplicationServices:
|
|
|
800
887
|
seed: int,
|
|
801
888
|
callback_url: str | None,
|
|
802
889
|
execution: ExecutionOptions,
|
|
890
|
+
megapixel_ratio: float = 1.0,
|
|
803
891
|
) -> OperationResult:
|
|
804
892
|
payload = build_image_edit_payload(
|
|
805
893
|
prompt=prompt,
|
|
@@ -807,6 +895,7 @@ class ApplicationServices:
|
|
|
807
895
|
model=model,
|
|
808
896
|
image_size=image_size,
|
|
809
897
|
resolution=resolution,
|
|
898
|
+
megapixel_ratio=megapixel_ratio,
|
|
810
899
|
seed=seed,
|
|
811
900
|
callback_url=callback_url,
|
|
812
901
|
)
|
|
@@ -885,10 +974,9 @@ class ApplicationServices:
|
|
|
885
974
|
duration: int | None,
|
|
886
975
|
resolution: str | None,
|
|
887
976
|
aspect_ratio: str | None,
|
|
888
|
-
lora_high_url: str | None = None,
|
|
889
|
-
lora_low_url: str | None = None,
|
|
890
977
|
reference_images: list[str] | None = None,
|
|
891
978
|
reference_videos: list[str] | None = None,
|
|
979
|
+
reference_audios: list[str] | None = None,
|
|
892
980
|
image: str | None = None,
|
|
893
981
|
last_image: str | None = None,
|
|
894
982
|
seed: int | None = None,
|
|
@@ -902,10 +990,9 @@ class ApplicationServices:
|
|
|
902
990
|
duration=duration,
|
|
903
991
|
resolution=resolution,
|
|
904
992
|
aspect_ratio=aspect_ratio,
|
|
905
|
-
lora_high_url=lora_high_url,
|
|
906
|
-
lora_low_url=lora_low_url,
|
|
907
993
|
reference_images=reference_images or [],
|
|
908
994
|
reference_videos=reference_videos or [],
|
|
995
|
+
reference_audios=reference_audios or [],
|
|
909
996
|
image=image,
|
|
910
997
|
last_image=last_image,
|
|
911
998
|
seed=seed,
|
|
@@ -966,11 +1053,15 @@ class ApplicationServices:
|
|
|
966
1053
|
task_id: str | None,
|
|
967
1054
|
resolution: str,
|
|
968
1055
|
execution: ExecutionOptions,
|
|
1056
|
+
model: str = "seedvr2",
|
|
1057
|
+
callback_url: str | None = None,
|
|
969
1058
|
) -> OperationResult:
|
|
970
1059
|
payload = build_video_upscale_payload(
|
|
971
1060
|
video=video,
|
|
972
1061
|
video_from_task_id=task_id,
|
|
973
1062
|
resolution=resolution,
|
|
1063
|
+
model=model,
|
|
1064
|
+
callback_url=callback_url,
|
|
974
1065
|
)
|
|
975
1066
|
return self._execute_async(
|
|
976
1067
|
endpoint="/v1/video_upscale",
|
|
@@ -1169,8 +1260,10 @@ class ApplicationServices:
|
|
|
1169
1260
|
path = operation.path
|
|
1170
1261
|
resolved_method = operation.method
|
|
1171
1262
|
resolved_method = resolved_method or "POST"
|
|
1172
|
-
if path
|
|
1263
|
+
if path in {"/v1/video_edit", "/v1/video_generate"}:
|
|
1173
1264
|
normalize_video_edit_content(payload)
|
|
1265
|
+
if path == "/v1/image_vectorize" and isinstance(payload.get("image_url"), str):
|
|
1266
|
+
payload["image_url"] = media_value(payload["image_url"])
|
|
1174
1267
|
if help_schema:
|
|
1175
1268
|
return OperationResult(
|
|
1176
1269
|
value=operation_help(
|
|
@@ -1181,6 +1274,14 @@ class ApplicationServices:
|
|
|
1181
1274
|
schema_source=schema_source,
|
|
1182
1275
|
)
|
|
1183
1276
|
)
|
|
1277
|
+
if path in {"/v1/image_generate", "/v1/image_edit", "/v1/video_generate"}:
|
|
1278
|
+
payload = normalize_grok_model(payload)
|
|
1279
|
+
if path == "/v1/video_generate" and payload.get("model") in get_args(
|
|
1280
|
+
VideoGenerateModel
|
|
1281
|
+
):
|
|
1282
|
+
_VIDEO_GENERATE_ADAPTER.validate_python(payload, extra="ignore")
|
|
1283
|
+
if path == "/v1/image_vectorize":
|
|
1284
|
+
ImageVectorizePayload.model_validate(payload)
|
|
1184
1285
|
if path == "/v1/video_edit":
|
|
1185
1286
|
# Generic callers may send forward-compatible fields that the local
|
|
1186
1287
|
# specialized model does not know yet; validate known semantics
|
|
@@ -1205,7 +1306,12 @@ class ApplicationServices:
|
|
|
1205
1306
|
method=resolved_method,
|
|
1206
1307
|
payload=payload,
|
|
1207
1308
|
execution=execution,
|
|
1208
|
-
fallback_extension=
|
|
1309
|
+
fallback_extension=(
|
|
1310
|
+
".svg"
|
|
1311
|
+
if path == "/v1/image_generate"
|
|
1312
|
+
and payload.get("model") in _IMAGE_GENERATE_BUILDERS
|
|
1313
|
+
else fallback_extension_for_endpoint(path)
|
|
1314
|
+
),
|
|
1209
1315
|
)
|
|
1210
1316
|
)
|
|
1211
1317
|
|
|
@@ -1322,17 +1428,19 @@ def parse_generic_payload(
|
|
|
1322
1428
|
|
|
1323
1429
|
|
|
1324
1430
|
def normalize_video_edit_content(payload: dict[str, Any]) -> None:
|
|
1325
|
-
"""Encode local generic
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1431
|
+
"""Encode local generic video frames and references as data URIs."""
|
|
1432
|
+
|
|
1433
|
+
for key in ("video_url", "image_url", "image_last_url"):
|
|
1434
|
+
value = payload.get(key)
|
|
1435
|
+
if isinstance(value, str):
|
|
1436
|
+
payload[key] = media_value(value)
|
|
1437
|
+
for key in ("reference_image_urls", "reference_video_urls", "reference_audio_urls"):
|
|
1438
|
+
values = payload.get(key)
|
|
1439
|
+
if isinstance(values, list):
|
|
1440
|
+
payload[key] = [
|
|
1441
|
+
media_value(value) if isinstance(value, str) else value
|
|
1442
|
+
for value in values
|
|
1443
|
+
]
|
|
1336
1444
|
keyframes = payload.get("keyframes")
|
|
1337
1445
|
if isinstance(keyframes, list):
|
|
1338
1446
|
for keyframe in keyframes:
|