@telepat/rilo 0.1.0

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.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +209 -0
  3. package/index.js +1 -0
  4. package/models/black-forest-labs__flux-2-pro.json +78 -0
  5. package/models/black-forest-labs__flux-schnell.json +95 -0
  6. package/models/bytedance__seedream-4.json +71 -0
  7. package/models/deepseek-ai__deepseek-v3.json +61 -0
  8. package/models/google__nano-banana-pro.json +92 -0
  9. package/models/google__veo-3.1-fast.json +93 -0
  10. package/models/google__veo-3.1.json +93 -0
  11. package/models/jaaari__kokoro-82m.json +86 -0
  12. package/models/kwaivgi__kling-v3-video.json +101 -0
  13. package/models/minimax__speech-02-turbo.json +141 -0
  14. package/models/pixverse__pixverse-v5.6.json +113 -0
  15. package/models/prunaai__z-image-turbo.json +107 -0
  16. package/models/resemble-ai__chatterbox-turbo.json +102 -0
  17. package/models/wan-video__wan-2.2-i2v-fast.json +139 -0
  18. package/package.json +67 -0
  19. package/src/api/firebaseFunction.js +46 -0
  20. package/src/api/middleware/auth.js +70 -0
  21. package/src/api/openapi/generateOpenApi.js +21 -0
  22. package/src/api/openapi/spec.js +831 -0
  23. package/src/api/routes/jobs.js +45 -0
  24. package/src/api/routes/projectAssets.js +63 -0
  25. package/src/api/routes/projects.js +647 -0
  26. package/src/api/routes/webhooks.js +13 -0
  27. package/src/api/server.js +88 -0
  28. package/src/backends/firebaseClient.js +57 -0
  29. package/src/backends/outputBackend.js +186 -0
  30. package/src/backends/projectMetadataBackend.js +550 -0
  31. package/src/cli/commands/openHome.js +70 -0
  32. package/src/cli/commands/settingsFlow.js +196 -0
  33. package/src/cli/index.js +192 -0
  34. package/src/config/env.js +158 -0
  35. package/src/config/keystore.js +175 -0
  36. package/src/config/models.js +281 -0
  37. package/src/config/settingsSchema.js +214 -0
  38. package/src/media/ffmpeg.js +144 -0
  39. package/src/media/files.js +77 -0
  40. package/src/media/subtitles.js +444 -0
  41. package/src/observability/apiTrace.js +17 -0
  42. package/src/observability/logger.js +7 -0
  43. package/src/observability/metrics.js +10 -0
  44. package/src/pipeline/inputSanitizer.js +6 -0
  45. package/src/pipeline/orchestrator.js +1669 -0
  46. package/src/policy/contentGuardrails.js +30 -0
  47. package/src/providers/predictions.js +188 -0
  48. package/src/providers/replicateClient.js +12 -0
  49. package/src/steps/alignSubtitles.js +156 -0
  50. package/src/steps/burnInSubtitles.js +22 -0
  51. package/src/steps/composeFinalVideo.js +57 -0
  52. package/src/steps/generateKeyframes.js +70 -0
  53. package/src/steps/generateVideoSegments.js +95 -0
  54. package/src/steps/generateVoiceover.js +128 -0
  55. package/src/steps/imageToVideoAdapters.js +100 -0
  56. package/src/steps/script.js +177 -0
  57. package/src/steps/textToImageAdapters.js +87 -0
  58. package/src/store/assetStore.js +5 -0
  59. package/src/store/jobStore.js +102 -0
  60. package/src/store/projectAnalyticsStore.js +625 -0
  61. package/src/store/projectStore.js +684 -0
  62. package/src/store/settingsStore.js +155 -0
  63. package/src/store/staleAssetStore.js +63 -0
  64. package/src/types/job.js +28 -0
  65. package/src/types/media.js +28 -0
  66. package/src/worker/processor.js +24 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Telepat contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,209 @@
1
+ # Rilo
2
+
3
+ [![CI](https://github.com/telepat-io/rilo/actions/workflows/ci.yml/badge.svg)](https://github.com/telepat-io/rilo/actions/workflows/ci.yml)
4
+ [![Coverage](https://codecov.io/gh/telepat-io/rilo/graph/badge.svg)](https://codecov.io/gh/telepat-io/rilo)
5
+ [![npm version](https://img.shields.io/npm/v/%40telepat%2Frilo)](https://www.npmjs.com/package/@telepat/rilo)
6
+ [![npm downloads](https://img.shields.io/npm/dm/%40telepat%2Frilo)](https://www.npmjs.com/package/@telepat/rilo)
7
+ [![Docs](https://img.shields.io/badge/docs-live-22c55e)](https://docs.telepat.io/rilo/)
8
+ [![License](https://img.shields.io/github/license/telepat-io/rilo)](./LICENSE)
9
+
10
+ Story-first vertical video generation.
11
+
12
+ Rilo turns one story into a complete short-form video pipeline:
13
+ - script generation
14
+ - voiceover generation
15
+ - keyframe generation
16
+ - video segment generation
17
+ - final composition
18
+ - optional subtitle alignment and burn-in
19
+
20
+ ## Why Rilo
21
+
22
+ - Built for vertical video workflows
23
+ - Checkpointed runs with resume support
24
+ - Targeted regeneration for faster iteration
25
+ - Model selection and per-model option overrides
26
+ - Local and Firebase output backends
27
+ - API, worker, and frontend flow for production usage
28
+
29
+ ## Quick Start
30
+
31
+ Requirements:
32
+ - Node.js 22+
33
+ - ffmpeg in PATH
34
+ - Replicate API token
35
+
36
+ Setup:
37
+
38
+ ```bash
39
+ npm install
40
+ cp .env.example .env
41
+ ```
42
+
43
+ Set required environment variables in .env, **or use the interactive settings command** (see below):
44
+
45
+ ```bash
46
+ RILO_REPLICATE_API_TOKEN=your-token
47
+ RILO_API_BEARER_TOKEN=your-api-bearer-token
48
+ ```
49
+
50
+ Run the full local stack:
51
+
52
+ ```bash
53
+ npm run dev:all
54
+ ```
55
+
56
+ Run a CLI generation:
57
+
58
+ ```bash
59
+ rilo --project demo --story-file ./story.txt
60
+ ```
61
+
62
+ ## Settings
63
+
64
+ Configure rilo interactively without editing files:
65
+
66
+ ```bash
67
+ rilo settings
68
+ ```
69
+
70
+ For local development in this repository:
71
+
72
+ ```bash
73
+ npm run dev -- settings
74
+ npm run dev -- --project demo --story-file ./story.txt
75
+ ```
76
+
77
+ This opens a menu where you can edit all non-sensitive settings and manage API tokens securely. Navigate with arrow keys, select with Enter, and use "Done" or "Cancel" to exit. You can also press Ctrl+C at any time to quit.
78
+
79
+ **What gets stored where:**
80
+
81
+ | Setting type | Storage |
82
+ |---|---|
83
+ | Replicate API Token, API Bearer Token | OS keystore (macOS Keychain, Windows Credential Manager, Linux Secret Service) — or an AES-256 encrypted file at `~/.rilo/.secrets` if no native keystore is available |
84
+ | All other settings (timeouts, limits, binary paths, etc.) | `~/.rilo/config.json` |
85
+
86
+ **Precedence** (highest → lowest): environment variable > `~/.rilo/config.json` > schema default.
87
+ If an env var is set, the settings command shows it as read-only and any stored value is ignored while the env var is present.
88
+
89
+ **Hidden from settings UI** (env-only): Firebase credentials, webhook settings, output backend, API port, custom output/projects directories.
90
+
91
+ ## Install from npm
92
+
93
+ ```bash
94
+ npm install -g @telepat/rilo
95
+ rilo --help
96
+ ```
97
+
98
+ Or without global install:
99
+
100
+ ```bash
101
+ npx @telepat/rilo --help
102
+ ```
103
+
104
+ ## CLI Quick Reference
105
+
106
+ ### Generate a video from a story
107
+
108
+ ```bash
109
+ rilo --project <name> --story-file <path>
110
+ ```
111
+
112
+ Examples:
113
+ ```bash
114
+ # First run: create project and start generation
115
+ rilo --project wedding-case --story-file ./story.txt
116
+
117
+ # On subsequent runs: reuse story
118
+ rilo --project wedding-case
119
+
120
+ # Force restart from earlier stages (after config change)
121
+ rilo --project wedding-case --force
122
+ ```
123
+
124
+ ### Configure settings
125
+
126
+ ```bash
127
+ rilo settings
128
+ ```
129
+
130
+ Opens an interactive menu to set API tokens, timeouts, and binary paths.
131
+
132
+ ### Open the Rilo home folder
133
+
134
+ ```bash
135
+ rilo home
136
+ ```
137
+
138
+ Opens `~/.rilo`, the default location for saved settings, projects, and generated output.
139
+
140
+ ### Help and version
141
+
142
+ ```bash
143
+ rilo --help # Show usage
144
+ rilo --version # Show version
145
+ ```
146
+
147
+ ### Invocation methods
148
+
149
+ | Method | Command |
150
+ |--------|---------|
151
+ | **Global install** | `rilo --project <name> --story-file <path>` |
152
+ | **No install (npx)** | `npx @telepat/rilo --project <name> --story-file <path>` |
153
+ | **Local dev** | `npm run dev -- --project <name> --story-file <path>` |
154
+
155
+ ### Key flags
156
+
157
+ | Flag | Type | Notes |
158
+ |------|------|-------|
159
+ | `--project` | `<name>` | **Required.** Project identifier; creates `projects/<name>/` |
160
+ | `--story-file` | `<path>` | Path to story text file (required on first run) |
161
+ | `--force` | flag | Restart from earlier stages; used after config changes |
162
+
163
+ ### Common tasks
164
+
165
+ **Update project config and regenerate:**
166
+ ```bash
167
+ # Edit projects/wedding-case/config.json (aspect ratio, models, etc.)
168
+ rilo --project wedding-case --force
169
+ ```
170
+
171
+ **Change app settings (tokens, timeouts, binary paths):**
172
+ ```bash
173
+ rilo settings
174
+ # Arrow keys to navigate, Enter to edit, "Done" to save
175
+ ```
176
+
177
+ **Open the default app folder for projects/output:**
178
+ ```bash
179
+ rilo home
180
+ # Opens ~/.rilo in your system file manager
181
+ ```
182
+
183
+ **Check where generated files are stored:**
184
+ ```bash
185
+ ls projects/wedding-case/
186
+ # Outputs: config.json, story.md, final.mp4, artifacts.json, run-state.json, assets/, logs/
187
+ ```
188
+
189
+ ---
190
+
191
+ ## CLI Documentation
192
+
193
+ For comprehensive CLI documentation, see:
194
+ - **[Quickstart](/docs.telepat.io/rilo/getting-started/quickstart)** — Step-by-step guide to your first generation
195
+ - **[CLI Reference](/docs.telepat.io/rilo/reference/cli-reference)** — All commands, flags, and invocation methods
196
+ - **[Complete Config Schema](/docs.telepat.io/rilo/reference/config-schema)** — Every config key with types and defaults
197
+ - **[Configuration Guide](/docs.telepat.io/rilo/guides/configuration)** — Project and app settings with examples
198
+ - **[Troubleshooting](/docs.telepat.io/rilo/guides/troubleshooting)** — Common errors and solutions
199
+ - **[Environment Variables](/docs.telepat.io/rilo/reference/environment-variables)** — Setting precedence and env var reference
200
+
201
+ ## Full Documentation
202
+
203
+ Guides, API reference, architecture notes, and advanced configuration:
204
+
205
+ https://docs.telepat.io/rilo/
206
+
207
+ ## License
208
+
209
+ MIT
package/index.js ADDED
@@ -0,0 +1 @@
1
+ export { api } from './src/api/firebaseFunction.js';
@@ -0,0 +1,78 @@
1
+ {
2
+ "modelId": "black-forest-labs/flux-2-pro",
3
+ "provider": "replicate",
4
+ "displayName": "FLUX 2 Pro",
5
+ "category": "image-generation",
6
+ "pricingSourceUrl": "https://replicate.com/black-forest-labs/flux-2-pro",
7
+ "pricingNotes": "Replicate lists multi-property pricing for run and input/output megapixels; this model currently uses best-effort cost fallback when exact rule mapping is unavailable.",
8
+ "pricing": {
9
+ "usdPerSecond": null,
10
+ "usdPer1kInputTokens": null,
11
+ "usdPer1kOutputTokens": null
12
+ },
13
+ "inputOptions": {
14
+ "userConfigurable": [
15
+ "safety_tolerance",
16
+ "seed",
17
+ "output_format",
18
+ "output_quality"
19
+ ],
20
+ "pipelineManaged": [
21
+ "prompt",
22
+ "aspect_ratio",
23
+ "width",
24
+ "height"
25
+ ],
26
+ "fields": {
27
+ "safety_tolerance": {
28
+ "type": "integer",
29
+ "default": 2,
30
+ "minimum": 1,
31
+ "maximum": 5
32
+ },
33
+ "seed": {
34
+ "type": "integer",
35
+ "nullable": true
36
+ },
37
+ "output_format": {
38
+ "type": "string",
39
+ "default": "webp",
40
+ "enum": [
41
+ "webp",
42
+ "png",
43
+ "jpg",
44
+ "jpeg"
45
+ ]
46
+ },
47
+ "output_quality": {
48
+ "type": "integer",
49
+ "default": 80,
50
+ "minimum": 0,
51
+ "maximum": 100
52
+ },
53
+ "prompt": {
54
+ "type": "string",
55
+ "required": true
56
+ },
57
+ "aspect_ratio": {
58
+ "type": "string",
59
+ "required": true,
60
+ "enum": [
61
+ "custom"
62
+ ]
63
+ },
64
+ "width": {
65
+ "type": "integer",
66
+ "required": true,
67
+ "minimum": 256,
68
+ "maximum": 2048
69
+ },
70
+ "height": {
71
+ "type": "integer",
72
+ "required": true,
73
+ "minimum": 256,
74
+ "maximum": 2048
75
+ }
76
+ }
77
+ }
78
+ }
@@ -0,0 +1,95 @@
1
+ {
2
+ "modelId": "black-forest-labs/flux-schnell",
3
+ "provider": "replicate",
4
+ "displayName": "FLUX Schnell",
5
+ "category": "image-generation",
6
+ "pricingSourceUrl": "https://replicate.com/black-forest-labs/flux-schnell",
7
+ "pricingNotes": "Replicate pricing: $3 per 1000 output images.",
8
+ "pricing": {
9
+ "usdPerSecond": null,
10
+ "usdPer1kInputTokens": null,
11
+ "usdPer1kOutputTokens": null
12
+ },
13
+ "pricingRules": {
14
+ "basis": "output_image_count",
15
+ "usdPerImage": 0.003
16
+ },
17
+ "inputOptions": {
18
+ "userConfigurable": [
19
+ "num_outputs",
20
+ "num_inference_steps",
21
+ "seed",
22
+ "output_format",
23
+ "output_quality",
24
+ "disable_safety_checker",
25
+ "go_fast",
26
+ "megapixels"
27
+ ],
28
+ "pipelineManaged": [
29
+ "prompt",
30
+ "aspect_ratio"
31
+ ],
32
+ "fields": {
33
+ "num_outputs": {
34
+ "type": "integer",
35
+ "default": 1,
36
+ "minimum": 1,
37
+ "maximum": 4
38
+ },
39
+ "num_inference_steps": {
40
+ "type": "integer",
41
+ "default": 4,
42
+ "minimum": 1,
43
+ "maximum": 4
44
+ },
45
+ "seed": {
46
+ "type": "integer",
47
+ "nullable": true
48
+ },
49
+ "output_format": {
50
+ "type": "string",
51
+ "default": "webp",
52
+ "enum": [
53
+ "webp",
54
+ "jpg",
55
+ "png"
56
+ ]
57
+ },
58
+ "output_quality": {
59
+ "type": "integer",
60
+ "default": 80,
61
+ "minimum": 0,
62
+ "maximum": 100
63
+ },
64
+ "disable_safety_checker": {
65
+ "type": "boolean",
66
+ "default": false
67
+ },
68
+ "go_fast": {
69
+ "type": "boolean",
70
+ "default": true
71
+ },
72
+ "megapixels": {
73
+ "type": "string",
74
+ "default": "1",
75
+ "allowAnyString": true,
76
+ "recommendedValues": [
77
+ "1"
78
+ ]
79
+ },
80
+ "prompt": {
81
+ "type": "string",
82
+ "required": true
83
+ },
84
+ "aspect_ratio": {
85
+ "type": "string",
86
+ "required": true,
87
+ "enum": [
88
+ "1:1",
89
+ "16:9",
90
+ "9:16"
91
+ ]
92
+ }
93
+ }
94
+ }
95
+ }
@@ -0,0 +1,71 @@
1
+ {
2
+ "modelId": "bytedance/seedream-4",
3
+ "provider": "replicate",
4
+ "displayName": "Seedream 4",
5
+ "category": "image-generation",
6
+ "pricingSourceUrl": "https://replicate.com/bytedance/seedream-4",
7
+ "pricingNotes": "Replicate pricing: $0.03 per output image.",
8
+ "pricing": {
9
+ "usdPerSecond": null,
10
+ "usdPer1kInputTokens": null,
11
+ "usdPer1kOutputTokens": null
12
+ },
13
+ "pricingRules": {
14
+ "basis": "output_image_count",
15
+ "usdPerImage": 0.03
16
+ },
17
+ "inputOptions": {
18
+ "userConfigurable": [
19
+ "size",
20
+ "sequential_image_generation",
21
+ "max_images",
22
+ "enhance_prompt"
23
+ ],
24
+ "pipelineManaged": [
25
+ "prompt",
26
+ "aspect_ratio"
27
+ ],
28
+ "fields": {
29
+ "size": {
30
+ "type": "string",
31
+ "default": "2K",
32
+ "enum": [
33
+ "1K",
34
+ "2K",
35
+ "4K"
36
+ ]
37
+ },
38
+ "sequential_image_generation": {
39
+ "type": "string",
40
+ "default": "disabled",
41
+ "enum": [
42
+ "disabled",
43
+ "auto"
44
+ ]
45
+ },
46
+ "max_images": {
47
+ "type": "integer",
48
+ "default": 1,
49
+ "minimum": 1,
50
+ "maximum": 15
51
+ },
52
+ "enhance_prompt": {
53
+ "type": "boolean",
54
+ "default": true
55
+ },
56
+ "prompt": {
57
+ "type": "string",
58
+ "required": true
59
+ },
60
+ "aspect_ratio": {
61
+ "type": "string",
62
+ "required": true,
63
+ "enum": [
64
+ "1:1",
65
+ "16:9",
66
+ "9:16"
67
+ ]
68
+ }
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,61 @@
1
+ {
2
+ "modelId": "deepseek-ai/deepseek-v3",
3
+ "provider": "replicate",
4
+ "displayName": "DeepSeek V3",
5
+ "category": "text-generation",
6
+ "pricingSourceUrl": "https://replicate.com/deepseek-ai/deepseek-v3",
7
+ "pricingNotes": "Replicate page lists both input and output at $1.45 per million tokens.",
8
+ "pricing": {
9
+ "usdPerSecond": null,
10
+ "usdPer1kInputTokens": 0.00145,
11
+ "usdPer1kOutputTokens": 0.00145
12
+ },
13
+ "inputOptions": {
14
+ "userConfigurable": [
15
+ "max_tokens",
16
+ "temperature",
17
+ "presence_penalty",
18
+ "frequency_penalty",
19
+ "top_p"
20
+ ],
21
+ "pipelineManaged": [
22
+ "prompt"
23
+ ],
24
+ "fields": {
25
+ "max_tokens": {
26
+ "type": "integer",
27
+ "default": 2048,
28
+ "minimum": 1,
29
+ "maximum": 8192
30
+ },
31
+ "temperature": {
32
+ "type": "number",
33
+ "default": 0.1,
34
+ "minimum": 0,
35
+ "maximum": 2
36
+ },
37
+ "presence_penalty": {
38
+ "type": "number",
39
+ "default": 0,
40
+ "minimum": -2,
41
+ "maximum": 2
42
+ },
43
+ "frequency_penalty": {
44
+ "type": "number",
45
+ "default": 0,
46
+ "minimum": -2,
47
+ "maximum": 2
48
+ },
49
+ "top_p": {
50
+ "type": "number",
51
+ "default": 1,
52
+ "minimum": 0,
53
+ "maximum": 1
54
+ },
55
+ "prompt": {
56
+ "type": "string",
57
+ "required": true
58
+ }
59
+ }
60
+ }
61
+ }
@@ -0,0 +1,92 @@
1
+ {
2
+ "modelId": "google/nano-banana-pro",
3
+ "provider": "replicate",
4
+ "displayName": "Nano Banana Pro",
5
+ "category": "image-generation",
6
+ "pricingSourceUrl": "https://replicate.com/google/nano-banana-pro",
7
+ "pricingNotes": "Replicate pricing by target resolution: 1K/2K=$0.15 per output image, 4K=$0.30 per output image, fallback tier=$0.035 per output image.",
8
+ "pricing": {
9
+ "usdPerSecond": null,
10
+ "usdPer1kInputTokens": null,
11
+ "usdPer1kOutputTokens": null
12
+ },
13
+ "pricingRules": {
14
+ "basis": "output_image_resolution",
15
+ "tiers": [
16
+ {
17
+ "resolution": "1K",
18
+ "usdPerImage": 0.15
19
+ },
20
+ {
21
+ "resolution": "2K",
22
+ "usdPerImage": 0.15
23
+ },
24
+ {
25
+ "resolution": "4K",
26
+ "usdPerImage": 0.3
27
+ },
28
+ {
29
+ "resolution": "fallback",
30
+ "usdPerImage": 0.035
31
+ }
32
+ ]
33
+ },
34
+ "inputOptions": {
35
+ "userConfigurable": [
36
+ "resolution",
37
+ "output_format",
38
+ "safety_filter_level",
39
+ "allow_fallback_model"
40
+ ],
41
+ "pipelineManaged": [
42
+ "prompt",
43
+ "aspect_ratio"
44
+ ],
45
+ "fields": {
46
+ "resolution": {
47
+ "type": "string",
48
+ "default": "2K",
49
+ "enum": [
50
+ "1K",
51
+ "2K",
52
+ "4K"
53
+ ]
54
+ },
55
+ "output_format": {
56
+ "type": "string",
57
+ "default": "jpg",
58
+ "enum": [
59
+ "jpg",
60
+ "png",
61
+ "webp"
62
+ ]
63
+ },
64
+ "safety_filter_level": {
65
+ "type": "string",
66
+ "default": "block_only_high",
67
+ "enum": [
68
+ "block_low_and_above",
69
+ "block_medium_and_above",
70
+ "block_only_high"
71
+ ]
72
+ },
73
+ "allow_fallback_model": {
74
+ "type": "boolean",
75
+ "default": false
76
+ },
77
+ "prompt": {
78
+ "type": "string",
79
+ "required": true
80
+ },
81
+ "aspect_ratio": {
82
+ "type": "string",
83
+ "required": true,
84
+ "enum": [
85
+ "1:1",
86
+ "16:9",
87
+ "9:16"
88
+ ]
89
+ }
90
+ }
91
+ }
92
+ }