@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.
Files changed (2) hide show
  1. package/dist/index.js +176 -5
  2. 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 \u2014 standard (seedance-2, higher quality) or fast (seedance-2-fast, iterative workflows)"),
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 \u2014 480p for faster, 720p for balance"),
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 \u2014 multimodal inputs (image/video/audio references), native audio generation, standard and fast modes",
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 \u2014 "standard" or "fast" (default: standard)',
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 \u2014 "480p" or "720p" (default: 720p)',
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.1.1",
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-ai-mcp-server.git"
32
+ "url": "git+https://github.com/felores/kie-cli-mcp.git"
33
33
  },
34
- "homepage": "https://github.com/felores/kie-ai-mcp-server#readme",
34
+ "homepage": "https://github.com/felores/kie-cli-mcp#readme",
35
35
  "bugs": {
36
- "url": "https://github.com/felores/kie-ai-mcp-server/issues"
36
+ "url": "https://github.com/felores/kie-cli-mcp/issues"
37
37
  },
38
38
  "publishConfig": {
39
39
  "registry": "https://registry.npmjs.org/",