dantelabs-agentic-school 1.0.0 â 1.2.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.
- package/.claude-plugin/marketplace.json +11 -53
- package/cli/bin/cli.js +31 -8
- package/cli/src/commands/info.js +15 -11
- package/cli/src/commands/install.js +53 -29
- package/cli/src/commands/list.js +28 -22
- package/cli/src/commands/uninstall.js +23 -16
- package/cli/src/i18n/index.js +96 -0
- package/cli/src/i18n/locales/en.js +107 -0
- package/cli/src/i18n/locales/ko.js +107 -0
- package/cli/src/lib/config.js +116 -1
- package/cli/src/lib/installer.js +106 -3
- package/package.json +1 -1
- package/plugins/brand-analytics/plugin.json +9 -0
- package/plugins/campaign-orchestration/plugin.json +9 -0
- package/plugins/common/plugin.json +9 -0
- package/plugins/common/skills/kie-image-generator/.env.example +4 -0
- package/plugins/common/skills/kie-image-generator/SKILL.md +281 -0
- package/plugins/common/skills/kie-image-generator/references/api_docs.md +358 -0
- package/plugins/common/skills/kie-image-generator/scripts/__pycache__/utils.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/generate_image.py +285 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__init__.py +19 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/__init__.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/flux_kontext.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/gpt4o.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/ideogram.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/imagen.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/nano_banana.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/nano_banana_edit.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/nano_banana_pro.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/seedream.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/__pycache__/seedream_edit.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/flux_kontext.py +36 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/gpt4o.py +36 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/ideogram.py +85 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/imagen.py +48 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/nano_banana.py +40 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/nano_banana_edit.py +55 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/nano_banana_pro.py +47 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/seedream.py +51 -0
- package/plugins/common/skills/kie-image-generator/scripts/models/seedream_edit.py +66 -0
- package/plugins/common/skills/kie-image-generator/scripts/utils.py +706 -0
- package/plugins/common/skills/kie-video-generator/SKILL.md +258 -0
- package/plugins/common/skills/kie-video-generator/references/api_docs.md +202 -0
- package/plugins/common/skills/kie-video-generator/scripts/__pycache__/utils.cpython-313.pyc +0 -0
- package/plugins/common/skills/kie-video-generator/scripts/generate_video.py +356 -0
- package/plugins/common/skills/kie-video-generator/scripts/models/__init__.py +4 -0
- package/plugins/common/skills/kie-video-generator/scripts/utils.py +617 -0
- package/plugins/content-creation/plugin.json +9 -0
- package/plugins/creative-production/plugin.json +9 -0
- package/plugins/customer-segmentation/plugin.json +9 -0
- package/plugins/market-research/plugin.json +9 -0
- package/plugins/persona-builder/plugin.json +9 -0
- package/plugins/social-strategy/plugin.json +9 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Kie.ai Video Generation CLI
|
|
4
|
+
|
|
5
|
+
Generate videos using Kie.ai's diverse AI models with automatic
|
|
6
|
+
credit tracking and interactive model selection.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
import argparse
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Dict, Any, Optional, List
|
|
13
|
+
|
|
14
|
+
# Add parent directory to path
|
|
15
|
+
sys.path.insert(0, str(Path(__file__).parent))
|
|
16
|
+
|
|
17
|
+
from utils import (
|
|
18
|
+
load_api_key,
|
|
19
|
+
get_credits,
|
|
20
|
+
print_credits,
|
|
21
|
+
print_models,
|
|
22
|
+
select_model_interactive,
|
|
23
|
+
confirm_generation,
|
|
24
|
+
submit_task,
|
|
25
|
+
poll_task,
|
|
26
|
+
download_video,
|
|
27
|
+
generate_filename,
|
|
28
|
+
MODELS,
|
|
29
|
+
CREDIT_TO_USD
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def build_payload(args, model_id: str) -> Dict[str, Any]:
|
|
34
|
+
"""Build request payload based on model and arguments."""
|
|
35
|
+
model = MODELS.get(model_id)
|
|
36
|
+
if not model:
|
|
37
|
+
raise ValueError(f"Unknown model: {model_id}")
|
|
38
|
+
|
|
39
|
+
payload = {'prompt': args.prompt}
|
|
40
|
+
|
|
41
|
+
# Veo 3 specific
|
|
42
|
+
if model_id in ['veo3', 'veo3-fast']:
|
|
43
|
+
if args.image:
|
|
44
|
+
payload['imageUrls'] = [args.image]
|
|
45
|
+
if args.end_image:
|
|
46
|
+
payload['imageUrls'].append(args.end_image)
|
|
47
|
+
payload['generationType'] = 'FIRST_AND_LAST_FRAMES_2_VIDEO'
|
|
48
|
+
else:
|
|
49
|
+
payload['generationType'] = 'REFERENCE_2_VIDEO'
|
|
50
|
+
else:
|
|
51
|
+
payload['generationType'] = 'TEXT_2_VIDEO'
|
|
52
|
+
|
|
53
|
+
if args.aspect_ratio:
|
|
54
|
+
payload['aspectRatio'] = args.aspect_ratio
|
|
55
|
+
if args.seed:
|
|
56
|
+
payload['seeds'] = args.seed
|
|
57
|
+
|
|
58
|
+
# Sora 2 specific
|
|
59
|
+
elif 'sora-2' in model_id:
|
|
60
|
+
if args.aspect_ratio:
|
|
61
|
+
ar_map = {'16:9': 'landscape', '9:16': 'portrait'}
|
|
62
|
+
payload['aspect_ratio'] = ar_map.get(args.aspect_ratio, args.aspect_ratio)
|
|
63
|
+
if args.frames:
|
|
64
|
+
payload['n_frames'] = str(args.frames)
|
|
65
|
+
if args.remove_watermark:
|
|
66
|
+
payload['remove_watermark'] = True
|
|
67
|
+
|
|
68
|
+
# Kling specific
|
|
69
|
+
elif 'kling' in model_id:
|
|
70
|
+
if args.image:
|
|
71
|
+
payload['image_urls'] = [args.image]
|
|
72
|
+
if args.duration:
|
|
73
|
+
payload['duration'] = str(args.duration)
|
|
74
|
+
# aspect_ratio is required for Kling
|
|
75
|
+
payload['aspect_ratio'] = args.aspect_ratio or '16:9'
|
|
76
|
+
if args.sound:
|
|
77
|
+
payload['sound'] = True
|
|
78
|
+
else:
|
|
79
|
+
payload['sound'] = False
|
|
80
|
+
|
|
81
|
+
# Wan specific
|
|
82
|
+
elif 'wan' in model_id:
|
|
83
|
+
if args.image:
|
|
84
|
+
payload['image_url'] = args.image
|
|
85
|
+
if args.duration:
|
|
86
|
+
payload['duration'] = str(args.duration)
|
|
87
|
+
if args.resolution:
|
|
88
|
+
payload['resolution'] = args.resolution
|
|
89
|
+
|
|
90
|
+
# Hailuo specific
|
|
91
|
+
elif 'hailuo' in model_id:
|
|
92
|
+
if args.image:
|
|
93
|
+
payload['image_url'] = args.image
|
|
94
|
+
if args.end_image:
|
|
95
|
+
payload['end_image_url'] = args.end_image
|
|
96
|
+
if args.duration:
|
|
97
|
+
payload['duration'] = str(args.duration)
|
|
98
|
+
if args.resolution:
|
|
99
|
+
res_map = {'512p': '512P', '768p': '768P'}
|
|
100
|
+
payload['resolution'] = res_map.get(args.resolution.lower(), args.resolution)
|
|
101
|
+
if args.prompt_optimizer:
|
|
102
|
+
payload['prompt_optimizer'] = True
|
|
103
|
+
|
|
104
|
+
# Seedance specific
|
|
105
|
+
elif 'seedance' in model_id:
|
|
106
|
+
if args.image:
|
|
107
|
+
# Seedance 1.5 Pro uses input_urls, V1 series uses image_url
|
|
108
|
+
if '1.5' in model_id or 'seedance-1' in model_id:
|
|
109
|
+
payload['input_urls'] = [args.image]
|
|
110
|
+
else:
|
|
111
|
+
payload['image_url'] = args.image
|
|
112
|
+
if args.duration:
|
|
113
|
+
payload['duration'] = str(args.duration)
|
|
114
|
+
if args.aspect_ratio:
|
|
115
|
+
payload['aspect_ratio'] = args.aspect_ratio
|
|
116
|
+
if args.resolution:
|
|
117
|
+
payload['resolution'] = args.resolution
|
|
118
|
+
if args.fixed_lens:
|
|
119
|
+
payload['fixed_lens'] = True
|
|
120
|
+
if args.generate_audio:
|
|
121
|
+
payload['generate_audio'] = True
|
|
122
|
+
|
|
123
|
+
# Grok specific
|
|
124
|
+
elif 'grok' in model_id:
|
|
125
|
+
if args.image:
|
|
126
|
+
payload['image_urls'] = [args.image]
|
|
127
|
+
# mode: fun, normal, spicy (default: normal)
|
|
128
|
+
payload['mode'] = 'normal'
|
|
129
|
+
|
|
130
|
+
return payload
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def parse_arguments():
|
|
134
|
+
"""Parse command-line arguments."""
|
|
135
|
+
parser = argparse.ArgumentParser(
|
|
136
|
+
description='Generate videos using Kie.ai models',
|
|
137
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
138
|
+
epilog="""
|
|
139
|
+
Examples:
|
|
140
|
+
%(prog)s --credits # Check available credits
|
|
141
|
+
%(prog)s --list-models # List all models with pricing
|
|
142
|
+
%(prog)s "a sunset over the ocean" # Interactive model selection
|
|
143
|
+
%(prog)s "cyberpunk city" --model veo3-fast # Direct model selection
|
|
144
|
+
%(prog)s "animate this" --model kling-2.6-i2v --image https://example.com/img.jpg
|
|
145
|
+
"""
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Positional
|
|
149
|
+
parser.add_argument(
|
|
150
|
+
'prompt',
|
|
151
|
+
nargs='?',
|
|
152
|
+
help='Text prompt for video generation'
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Info commands
|
|
156
|
+
parser.add_argument(
|
|
157
|
+
'--credits', '-c',
|
|
158
|
+
action='store_true',
|
|
159
|
+
help='Show current account credits'
|
|
160
|
+
)
|
|
161
|
+
parser.add_argument(
|
|
162
|
+
'--list-models', '-l',
|
|
163
|
+
action='store_true',
|
|
164
|
+
help='List all available models with pricing'
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
# Model selection
|
|
168
|
+
parser.add_argument(
|
|
169
|
+
'--model', '-m',
|
|
170
|
+
choices=list(MODELS.keys()),
|
|
171
|
+
help='Model to use (interactive selection if not specified)'
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# Image inputs
|
|
175
|
+
parser.add_argument(
|
|
176
|
+
'--image', '-i',
|
|
177
|
+
help='Input image URL for image-to-video models'
|
|
178
|
+
)
|
|
179
|
+
parser.add_argument(
|
|
180
|
+
'--end-image',
|
|
181
|
+
help='End frame image URL (for transition videos)'
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# Common parameters
|
|
185
|
+
parser.add_argument(
|
|
186
|
+
'--aspect-ratio', '-ar',
|
|
187
|
+
help='Aspect ratio (e.g., 16:9, 9:16, 1:1)'
|
|
188
|
+
)
|
|
189
|
+
parser.add_argument(
|
|
190
|
+
'--duration', '-d',
|
|
191
|
+
type=int,
|
|
192
|
+
help='Video duration in seconds'
|
|
193
|
+
)
|
|
194
|
+
parser.add_argument(
|
|
195
|
+
'--resolution', '-r',
|
|
196
|
+
help='Output resolution (e.g., 720p, 1080p)'
|
|
197
|
+
)
|
|
198
|
+
parser.add_argument(
|
|
199
|
+
'--seed',
|
|
200
|
+
type=int,
|
|
201
|
+
help='Random seed for reproducibility'
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
# Model-specific options
|
|
205
|
+
parser.add_argument(
|
|
206
|
+
'--sound',
|
|
207
|
+
action='store_true',
|
|
208
|
+
help='Include sound (Kling models)'
|
|
209
|
+
)
|
|
210
|
+
parser.add_argument(
|
|
211
|
+
'--frames',
|
|
212
|
+
type=int,
|
|
213
|
+
choices=[10, 15],
|
|
214
|
+
help='Number of frames (Sora 2)'
|
|
215
|
+
)
|
|
216
|
+
parser.add_argument(
|
|
217
|
+
'--remove-watermark',
|
|
218
|
+
action='store_true',
|
|
219
|
+
help='Remove watermark (Sora 2)'
|
|
220
|
+
)
|
|
221
|
+
parser.add_argument(
|
|
222
|
+
'--fixed-lens',
|
|
223
|
+
action='store_true',
|
|
224
|
+
help='Fixed camera lens (Seedance)'
|
|
225
|
+
)
|
|
226
|
+
parser.add_argument(
|
|
227
|
+
'--generate-audio',
|
|
228
|
+
action='store_true',
|
|
229
|
+
help='Generate audio (Seedance)'
|
|
230
|
+
)
|
|
231
|
+
parser.add_argument(
|
|
232
|
+
'--prompt-optimizer',
|
|
233
|
+
action='store_true',
|
|
234
|
+
help='Use prompt optimizer (Hailuo)'
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
# Output options
|
|
238
|
+
parser.add_argument(
|
|
239
|
+
'--output', '-o',
|
|
240
|
+
type=Path,
|
|
241
|
+
default=Path.home() / 'Downloads' / 'videos',
|
|
242
|
+
help='Output directory (default: ~/Downloads/videos/)'
|
|
243
|
+
)
|
|
244
|
+
parser.add_argument(
|
|
245
|
+
'--filename', '-f',
|
|
246
|
+
help='Output filename (without extension)'
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
# Flags
|
|
250
|
+
parser.add_argument(
|
|
251
|
+
'--yes', '-y',
|
|
252
|
+
action='store_true',
|
|
253
|
+
help='Skip confirmation prompts'
|
|
254
|
+
)
|
|
255
|
+
parser.add_argument(
|
|
256
|
+
'--no-download',
|
|
257
|
+
action='store_true',
|
|
258
|
+
help='Skip video download (print URL only)'
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
return parser.parse_args()
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def main():
|
|
265
|
+
"""Main execution function."""
|
|
266
|
+
args = parse_arguments()
|
|
267
|
+
|
|
268
|
+
try:
|
|
269
|
+
# Load API key
|
|
270
|
+
api_key = load_api_key()
|
|
271
|
+
|
|
272
|
+
# Handle info commands
|
|
273
|
+
if args.credits:
|
|
274
|
+
print_credits(api_key)
|
|
275
|
+
return 0
|
|
276
|
+
|
|
277
|
+
if args.list_models:
|
|
278
|
+
print_models()
|
|
279
|
+
return 0
|
|
280
|
+
|
|
281
|
+
# Require prompt for generation
|
|
282
|
+
if not args.prompt:
|
|
283
|
+
print("â Error: Please provide a prompt or use --credits / --list-models")
|
|
284
|
+
print(" Run with --help for usage information")
|
|
285
|
+
return 1
|
|
286
|
+
|
|
287
|
+
print("đŹ Kie.ai Video Generator")
|
|
288
|
+
print(f"Prompt: {args.prompt}\n")
|
|
289
|
+
|
|
290
|
+
# Get current credits
|
|
291
|
+
credits, usd = get_credits(api_key)
|
|
292
|
+
print(f"đ° Current Balance: {credits:,} credits (${usd:.2f})")
|
|
293
|
+
|
|
294
|
+
# Model selection
|
|
295
|
+
has_image = bool(args.image)
|
|
296
|
+
|
|
297
|
+
if args.model:
|
|
298
|
+
model_id = args.model
|
|
299
|
+
# Validate image requirement
|
|
300
|
+
model = MODELS[model_id]
|
|
301
|
+
if model['type'] == 'image-to-video' and not has_image:
|
|
302
|
+
print(f"\nâ ď¸ Model '{model_id}' requires an image input.")
|
|
303
|
+
print(" Use --image <url> to provide an image.")
|
|
304
|
+
return 1
|
|
305
|
+
else:
|
|
306
|
+
# Interactive selection
|
|
307
|
+
model_id = select_model_interactive(args.prompt, has_image)
|
|
308
|
+
if not model_id:
|
|
309
|
+
print("\nđ Generation cancelled.")
|
|
310
|
+
return 0
|
|
311
|
+
|
|
312
|
+
# Confirm generation
|
|
313
|
+
if not args.yes:
|
|
314
|
+
if not confirm_generation(model_id, credits):
|
|
315
|
+
print("\nđ Generation cancelled.")
|
|
316
|
+
return 0
|
|
317
|
+
|
|
318
|
+
# Build payload
|
|
319
|
+
payload = build_payload(args, model_id)
|
|
320
|
+
print(f"\nđ Request payload: {payload}")
|
|
321
|
+
|
|
322
|
+
# Submit task
|
|
323
|
+
task_id = submit_task(api_key, model_id, payload)
|
|
324
|
+
|
|
325
|
+
# Poll for completion
|
|
326
|
+
video_url = poll_task(api_key, model_id, task_id)
|
|
327
|
+
|
|
328
|
+
print(f"\nđĽ Video URL: {video_url}")
|
|
329
|
+
|
|
330
|
+
# Download video
|
|
331
|
+
if not args.no_download:
|
|
332
|
+
filename = args.filename or generate_filename(model_id, args.prompt)
|
|
333
|
+
output_path = download_video(video_url, args.output, filename)
|
|
334
|
+
print(f"\n⨠Success! Video saved to: {output_path}")
|
|
335
|
+
else:
|
|
336
|
+
print("\n⨠Video generated successfully!")
|
|
337
|
+
|
|
338
|
+
# Report updated credits
|
|
339
|
+
new_credits, new_usd = get_credits(api_key)
|
|
340
|
+
used = credits - new_credits
|
|
341
|
+
print(f"\nđ° Credits used: {used} (${used * CREDIT_TO_USD:.2f})")
|
|
342
|
+
print(f" Remaining: {new_credits:,} credits (${new_usd:.2f})")
|
|
343
|
+
|
|
344
|
+
return 0
|
|
345
|
+
|
|
346
|
+
except KeyboardInterrupt:
|
|
347
|
+
print("\n\nâ ď¸ Operation cancelled by user")
|
|
348
|
+
return 130
|
|
349
|
+
|
|
350
|
+
except Exception as e:
|
|
351
|
+
print(f"\nâ Error: {e}", file=sys.stderr)
|
|
352
|
+
return 1
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
if __name__ == '__main__':
|
|
356
|
+
sys.exit(main())
|