@felores/kie-cli 0.1.1 → 0.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/dist/index.js +176 -5
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -150,7 +150,7 @@ var ElevenLabsSoundEffectsSchema = z.object({
|
|
|
150
150
|
var ByteDanceSeedanceVideoSchema = z.object({
|
|
151
151
|
prompt: z.string().min(3).max(2e4).describe("Text prompt for video generation (3-20000 characters)"),
|
|
152
152
|
// Mode: standard (seedance-2) or fast (seedance-2-fast)
|
|
153
|
-
mode: z.enum(["standard", "fast"]).default("standard").optional().describe("Generation mode
|
|
153
|
+
mode: z.enum(["standard", "fast"]).default("standard").optional().describe("Generation mode: standard (seedance-2, higher quality) or fast (seedance-2-fast, iterative workflows)"),
|
|
154
154
|
// Frame control
|
|
155
155
|
first_frame_url: z.string().url().optional().describe("URL of image to use as the first frame (optional)"),
|
|
156
156
|
last_frame_url: z.string().url().optional().describe("URL of image to use as the last frame (optional)"),
|
|
@@ -160,7 +160,7 @@ var ByteDanceSeedanceVideoSchema = z.object({
|
|
|
160
160
|
reference_audio_urls: z.array(z.string().url()).max(3).optional().describe("Reference audio for sound-guided generation (up to 3)"),
|
|
161
161
|
// Output settings
|
|
162
162
|
aspect_ratio: z.enum(["1:1", "9:16", "16:9", "4:3", "3:4", "21:9", "9:21", "adaptive"]).default("16:9").optional().describe("Aspect ratio of the generated video"),
|
|
163
|
-
resolution: z.enum(["480p", "720p"]).default("720p").optional().describe("Video resolution
|
|
163
|
+
resolution: z.enum(["480p", "720p"]).default("720p").optional().describe("Video resolution: 480p for faster, 720p for balance"),
|
|
164
164
|
duration: z.number().int().min(4).max(15).default(5).optional().describe("Duration of video in seconds (4-15)"),
|
|
165
165
|
// Audio & safety
|
|
166
166
|
generate_audio: z.boolean().default(true).optional().describe("Generate native audio for the video"),
|
|
@@ -624,6 +624,12 @@ var ListTasksSchema = z.object({
|
|
|
624
624
|
limit: z.number().int().max(100).default(20).describe("Maximum number of tasks to return"),
|
|
625
625
|
status: z.enum(["pending", "processing", "completed", "failed"]).optional().describe("Filter by status")
|
|
626
626
|
});
|
|
627
|
+
var WaitForTaskSchema = z.object({
|
|
628
|
+
task_id: z.string().min(1).describe("Task ID returned by a generation tool to wait for"),
|
|
629
|
+
timeout_seconds: z.number().int().min(5).max(600).default(180).describe("Max seconds to wait before giving up"),
|
|
630
|
+
interval_seconds: z.number().int().min(1).max(60).default(5).describe("Seconds between status checks while waiting"),
|
|
631
|
+
rendezvous_url: z.string().url().optional().describe("Optional callback rendezvous result base URL (e.g. https://felo-workers.felo.workers.dev/kie/result). Omit to poll the Kie API directly (the default). When set, or when KIE_AI_RESULT_URL / a KIE_AI_CALLBACK_URL ending in /kie/callback is configured, it waits on the rendezvous instead")
|
|
632
|
+
});
|
|
627
633
|
var Veo3Get1080pVideoSchema = z.object({
|
|
628
634
|
task_id: z.string().min(1).describe("Veo3 task ID to get 1080p video for"),
|
|
629
635
|
index: z.number().int().min(0).optional().describe("Video index (optional, for multiple video results)")
|
|
@@ -1447,7 +1453,7 @@ var TaskDatabase = class {
|
|
|
1447
1453
|
import { z as z2 } from "zod";
|
|
1448
1454
|
var bytedanceSeedanceVideoTool = {
|
|
1449
1455
|
name: "bytedance_seedance_video",
|
|
1450
|
-
description: "Generate videos with ByteDance Seedance 2.0
|
|
1456
|
+
description: "Generate videos with ByteDance Seedance 2.0: multimodal inputs (image/video/audio references), native audio generation, standard and fast modes",
|
|
1451
1457
|
category: "video",
|
|
1452
1458
|
schema: ByteDanceSeedanceVideoSchema,
|
|
1453
1459
|
async run(args, ctx) {
|
|
@@ -1510,14 +1516,14 @@ var bytedanceSeedanceVideoTool = {
|
|
|
1510
1516
|
if (error instanceof z2.ZodError) {
|
|
1511
1517
|
return ctx.formatError("bytedance_seedance_video", error, {
|
|
1512
1518
|
prompt: "Required: Text prompt for video generation (3-20000 characters)",
|
|
1513
|
-
mode: 'Optional: Generation mode
|
|
1519
|
+
mode: 'Optional: Generation mode: "standard" or "fast" (default: standard)',
|
|
1514
1520
|
first_frame_url: "Optional: URL of image to use as first frame",
|
|
1515
1521
|
last_frame_url: "Optional: URL of image to use as last frame",
|
|
1516
1522
|
reference_image_urls: "Optional: Reference images for style guidance (up to 9)",
|
|
1517
1523
|
reference_video_urls: "Optional: Reference videos for motion guidance (up to 3)",
|
|
1518
1524
|
reference_audio_urls: "Optional: Reference audio for sound-guided generation (up to 3)",
|
|
1519
1525
|
aspect_ratio: "Optional: Video aspect ratio (default: 16:9)",
|
|
1520
|
-
resolution: 'Optional: Video resolution
|
|
1526
|
+
resolution: 'Optional: Video resolution: "480p" or "720p" (default: 720p)',
|
|
1521
1527
|
duration: "Optional: Video duration in seconds 4-15 (default: 5)",
|
|
1522
1528
|
generate_audio: "Optional: Generate native audio (default: true)",
|
|
1523
1529
|
web_search: "Optional: Enable web search for prompt enhancement (default: false)",
|
|
@@ -3433,6 +3439,170 @@ var veo3Get1080pVideoTool = {
|
|
|
3433
3439
|
}
|
|
3434
3440
|
};
|
|
3435
3441
|
|
|
3442
|
+
// ../core/dist/tools/wait_for_task.js
|
|
3443
|
+
function resolveResultBase(explicit, ctx) {
|
|
3444
|
+
const strip = (u) => u.replace(/\/+$/, "");
|
|
3445
|
+
if (explicit)
|
|
3446
|
+
return strip(explicit);
|
|
3447
|
+
if (process.env.KIE_AI_RESULT_URL)
|
|
3448
|
+
return strip(process.env.KIE_AI_RESULT_URL);
|
|
3449
|
+
const callback = ctx.getCallbackUrl();
|
|
3450
|
+
if (callback.endsWith("/kie/callback")) {
|
|
3451
|
+
return callback.slice(0, -"/kie/callback".length) + "/kie/result";
|
|
3452
|
+
}
|
|
3453
|
+
return null;
|
|
3454
|
+
}
|
|
3455
|
+
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
3456
|
+
async function pollOnce(ctx, task_id) {
|
|
3457
|
+
try {
|
|
3458
|
+
const res = await getTaskStatusTool.run({ task_id }, ctx);
|
|
3459
|
+
return JSON.parse(res.content[0].text);
|
|
3460
|
+
} catch {
|
|
3461
|
+
return null;
|
|
3462
|
+
}
|
|
3463
|
+
}
|
|
3464
|
+
var waitForTaskTool = {
|
|
3465
|
+
name: "wait_for_task",
|
|
3466
|
+
description: "Wait for a generation task to complete in a single call, so you don't have to poll get_task_status repeatedly. Pass the task_id returned by any generation tool: it blocks until the result is ready (or the timeout) and returns the final URLs, streaming progress meanwhile. By default it polls the Kie API directly (no setup); if a callback rendezvous is configured (KIE_AI_RESULT_URL, rendezvous_url, or a KIE_AI_CALLBACK_URL ending in /kie/callback) it waits on that instead. Tip for long jobs: clients should enable resetTimeoutOnProgress with a generous maxTotalTimeout.",
|
|
3467
|
+
category: "utility",
|
|
3468
|
+
schema: WaitForTaskSchema,
|
|
3469
|
+
async run(args, ctx) {
|
|
3470
|
+
try {
|
|
3471
|
+
const { task_id, timeout_seconds = 180, interval_seconds = 5, rendezvous_url } = WaitForTaskSchema.parse(args);
|
|
3472
|
+
const base = resolveResultBase(rendezvous_url, ctx);
|
|
3473
|
+
const start = Date.now();
|
|
3474
|
+
const deadline = start + timeout_seconds * 1e3;
|
|
3475
|
+
const totalTicks = Math.max(1, Math.ceil(timeout_seconds / interval_seconds));
|
|
3476
|
+
let tick = 0;
|
|
3477
|
+
const elapsed = () => Math.round((Date.now() - start) / 1e3);
|
|
3478
|
+
if (base) {
|
|
3479
|
+
const url = `${base}/${encodeURIComponent(task_id)}`;
|
|
3480
|
+
while (Date.now() < deadline) {
|
|
3481
|
+
tick++;
|
|
3482
|
+
try {
|
|
3483
|
+
const res = await fetch(url);
|
|
3484
|
+
if (res.status === 200) {
|
|
3485
|
+
const data = await res.json();
|
|
3486
|
+
return {
|
|
3487
|
+
content: [
|
|
3488
|
+
{
|
|
3489
|
+
type: "text",
|
|
3490
|
+
text: JSON.stringify({
|
|
3491
|
+
success: true,
|
|
3492
|
+
task_id,
|
|
3493
|
+
status: data.status ?? "completed",
|
|
3494
|
+
elapsed_seconds: elapsed(),
|
|
3495
|
+
result_urls: data.urls ?? [],
|
|
3496
|
+
model: data.model ?? null,
|
|
3497
|
+
message: "Result received from rendezvous"
|
|
3498
|
+
}, null, 2)
|
|
3499
|
+
}
|
|
3500
|
+
]
|
|
3501
|
+
};
|
|
3502
|
+
}
|
|
3503
|
+
} catch {
|
|
3504
|
+
}
|
|
3505
|
+
await ctx.onProgress?.({
|
|
3506
|
+
progress: tick,
|
|
3507
|
+
total: totalTicks,
|
|
3508
|
+
message: `Waiting on rendezvous\u2026 ${elapsed()}s elapsed`
|
|
3509
|
+
});
|
|
3510
|
+
await sleep(interval_seconds * 1e3);
|
|
3511
|
+
}
|
|
3512
|
+
return {
|
|
3513
|
+
isError: true,
|
|
3514
|
+
content: [
|
|
3515
|
+
{
|
|
3516
|
+
type: "text",
|
|
3517
|
+
text: JSON.stringify({
|
|
3518
|
+
success: false,
|
|
3519
|
+
task_id,
|
|
3520
|
+
status: "timed_out",
|
|
3521
|
+
error: "timeout",
|
|
3522
|
+
elapsed_seconds: elapsed(),
|
|
3523
|
+
message: `No result after ${timeout_seconds}s. The task may still be running; retry wait_for_task or check get_task_status.`
|
|
3524
|
+
}, null, 2)
|
|
3525
|
+
}
|
|
3526
|
+
]
|
|
3527
|
+
};
|
|
3528
|
+
}
|
|
3529
|
+
while (Date.now() < deadline) {
|
|
3530
|
+
tick++;
|
|
3531
|
+
const details = await pollOnce(ctx, task_id);
|
|
3532
|
+
const task = await ctx.db.getTask(task_id);
|
|
3533
|
+
if (task?.status === "completed") {
|
|
3534
|
+
const fromDetails = details?.result_urls;
|
|
3535
|
+
const result_urls = fromDetails && fromDetails.length > 0 ? fromDetails : task.result_url ? [task.result_url] : [];
|
|
3536
|
+
return {
|
|
3537
|
+
content: [
|
|
3538
|
+
{
|
|
3539
|
+
type: "text",
|
|
3540
|
+
text: JSON.stringify({
|
|
3541
|
+
success: true,
|
|
3542
|
+
task_id,
|
|
3543
|
+
status: "completed",
|
|
3544
|
+
elapsed_seconds: elapsed(),
|
|
3545
|
+
result_urls,
|
|
3546
|
+
details,
|
|
3547
|
+
message: "Generation completed"
|
|
3548
|
+
}, null, 2)
|
|
3549
|
+
}
|
|
3550
|
+
]
|
|
3551
|
+
};
|
|
3552
|
+
}
|
|
3553
|
+
if (task?.status === "failed") {
|
|
3554
|
+
return {
|
|
3555
|
+
isError: true,
|
|
3556
|
+
content: [
|
|
3557
|
+
{
|
|
3558
|
+
type: "text",
|
|
3559
|
+
text: JSON.stringify({
|
|
3560
|
+
success: false,
|
|
3561
|
+
task_id,
|
|
3562
|
+
status: "failed",
|
|
3563
|
+
elapsed_seconds: elapsed(),
|
|
3564
|
+
error: task.error_message ?? "Generation failed",
|
|
3565
|
+
details,
|
|
3566
|
+
message: "Generation failed"
|
|
3567
|
+
}, null, 2)
|
|
3568
|
+
}
|
|
3569
|
+
]
|
|
3570
|
+
};
|
|
3571
|
+
}
|
|
3572
|
+
await ctx.onProgress?.({
|
|
3573
|
+
progress: tick,
|
|
3574
|
+
total: totalTicks,
|
|
3575
|
+
message: `Generating\u2026 ${elapsed()}s elapsed (status: ${task?.status ?? "pending"})`
|
|
3576
|
+
});
|
|
3577
|
+
await sleep(interval_seconds * 1e3);
|
|
3578
|
+
}
|
|
3579
|
+
return {
|
|
3580
|
+
isError: true,
|
|
3581
|
+
content: [
|
|
3582
|
+
{
|
|
3583
|
+
type: "text",
|
|
3584
|
+
text: JSON.stringify({
|
|
3585
|
+
success: false,
|
|
3586
|
+
task_id,
|
|
3587
|
+
status: "timed_out",
|
|
3588
|
+
error: "timeout",
|
|
3589
|
+
elapsed_seconds: elapsed(),
|
|
3590
|
+
message: `Still running after ${timeout_seconds}s. Call wait_for_task again with the same task_id, or check get_task_status.`
|
|
3591
|
+
}, null, 2)
|
|
3592
|
+
}
|
|
3593
|
+
]
|
|
3594
|
+
};
|
|
3595
|
+
} catch (error) {
|
|
3596
|
+
return ctx.formatError("wait_for_task", error, {
|
|
3597
|
+
task_id: "Required: task ID returned by a generation tool",
|
|
3598
|
+
timeout_seconds: "Optional: max seconds to wait (5-600, default: 180)",
|
|
3599
|
+
interval_seconds: "Optional: seconds between status checks (1-60, default: 5)",
|
|
3600
|
+
rendezvous_url: "Optional: rendezvous result base URL (e.g. https://host/kie/result); omit to poll the Kie API directly"
|
|
3601
|
+
});
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
};
|
|
3605
|
+
|
|
3436
3606
|
// ../core/dist/tools/wan_animate.js
|
|
3437
3607
|
import { z as z21 } from "zod";
|
|
3438
3608
|
var wanAnimateTool = {
|
|
@@ -3651,6 +3821,7 @@ var TOOL_REGISTRY = [
|
|
|
3651
3821
|
topazUpscaleImageTool,
|
|
3652
3822
|
veo3GenerateVideoTool,
|
|
3653
3823
|
veo3Get1080pVideoTool,
|
|
3824
|
+
waitForTaskTool,
|
|
3654
3825
|
wanAnimateTool,
|
|
3655
3826
|
wanVideoTool,
|
|
3656
3827
|
zImageTool
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@felores/kie-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Standalone CLI for Kie.ai APIs: generate images, video, music and speech from the terminal. Same models as the Kie.ai MCP server, no MCP client required.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"repository": {
|
|
31
31
|
"type": "git",
|
|
32
|
-
"url": "git+https://github.com/felores/kie-
|
|
32
|
+
"url": "git+https://github.com/felores/kie-cli-mcp.git"
|
|
33
33
|
},
|
|
34
|
-
"homepage": "https://github.com/felores/kie-
|
|
34
|
+
"homepage": "https://github.com/felores/kie-cli-mcp#readme",
|
|
35
35
|
"bugs": {
|
|
36
|
-
"url": "https://github.com/felores/kie-
|
|
36
|
+
"url": "https://github.com/felores/kie-cli-mcp/issues"
|
|
37
37
|
},
|
|
38
38
|
"publishConfig": {
|
|
39
39
|
"registry": "https://registry.npmjs.org/",
|