agnes-ai-cli 0.1.2 → 0.1.3

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/README.md CHANGED
@@ -29,10 +29,11 @@ agnes video text2video --prompt "a cinematic drone shot of waves at dusk"
29
29
  agnes video img2video --image ./frame.png --prompt "animate subtle rain and drifting fog"
30
30
  agnes video multivideo --image ./frame-a.png --image ./frame-b.png --prompt "blend these references into one motion concept"
31
31
  agnes video keyframes --image ./frame-a.png --image ./frame-b.png --prompt "morph between the two scenes"
32
- agnes video poll <task-id>
32
+ agnes video poll <video-or-task-id>
33
33
  ```
34
34
 
35
35
  Local media inputs are uploaded to a temporary public URL automatically. The default bridge tries x0.at first, then falls back to tmpfiles, Uguu, and Litterbox.
36
+ Video creation is asynchronous. Create commands print both `taskId` and `videoId` when Agnes returns them; use `videoId` with `agnes video poll`. Passing an older `taskId` still works through the legacy polling endpoint.
36
37
 
37
38
  ## JS API
38
39
 
package/dist/cli.js CHANGED
@@ -224,9 +224,9 @@ Examples:
224
224
  agnes video text2video --prompt "A cinematic beach scene at sunset"
225
225
  agnes video img2video --image ./frame.png --prompt "Add gentle wind and a soft push-in"
226
226
  agnes video keyframes --image ./a.png --image ./b.png --prompt "Transition between the frames"
227
- agnes video poll task_123
227
+ agnes video poll video_123
228
228
 
229
- Use this group for Agnes video task creation and polling. Video creation is asynchronous; poll returns the final result.
229
+ Use this group for Agnes video task creation and polling. Video creation is asynchronous; poll uses the recommended video_id endpoint and keeps task_id inputs compatible with the legacy endpoint.
230
230
  `);
231
231
  buildVideoGenerateCommand(video, "text2video", "Generate a video from text", async (client, options) => client.video.generate({
232
232
  mode: "text2video",
@@ -277,19 +277,19 @@ Use this group for Agnes video task creation and polling. Video creation is asyn
277
277
  video
278
278
  .command("poll")
279
279
  .description("Poll an Agnes video task until it finishes")
280
- .argument("<task-id>", "Task id returned by Agnes video creation")
281
- .option("--interval <seconds>", "Polling interval seconds", parseInteger, 3)
280
+ .argument("<video-or-task-id>", "Video id returned by Agnes video creation; task ids are accepted for legacy compatibility")
281
+ .option("--interval <seconds>", "Polling interval seconds", parseInteger, 5)
282
282
  .option("--timeout <seconds>", "Polling timeout seconds", parseInteger, 600)
283
283
  .option("--json", "Output JSON")
284
284
  .addHelpText("after", `
285
285
  Example:
286
- agnes video poll task_123 --interval 3 --timeout 600
286
+ agnes video poll video_123 --interval 5 --timeout 600
287
287
 
288
288
  Request shape:
289
- Polls Agnes /videos/{task_id} until the task completes, fails, or times out. Use this after any asynchronous video creation command.
289
+ Polls Agnes /agnesapi?video_id={video_id} until the task completes, fails, or times out. If you pass a task_ id, poll uses the legacy /videos/{task_id} endpoint for compatibility. Use this after any asynchronous video creation command.
290
290
  `)
291
- .action(async (taskId, options) => {
292
- const result = await client.video.poll(taskId, {
291
+ .action(async (id, options) => {
292
+ const result = await client.video.poll(id, {
293
293
  intervalSeconds: options.interval,
294
294
  timeoutSeconds: options.timeout,
295
295
  });
@@ -344,6 +344,7 @@ function buildVideoGenerateCommand(video, name, description, fn, imageMode = fal
344
344
  const task = result;
345
345
  printLines([
346
346
  `taskId: ${task.taskId}`,
347
+ task.videoId ? `videoId: ${task.videoId}` : undefined,
347
348
  `status: ${task.status}`,
348
349
  ]);
349
350
  });
package/dist/config.d.ts CHANGED
@@ -46,6 +46,7 @@ export type AgnesStatus = "queued" | "in_progress" | "completed" | "failed" | "t
46
46
  export interface NormalizedVideoTask {
47
47
  ok: true;
48
48
  taskId: string;
49
+ videoId?: string;
49
50
  status: AgnesStatus;
50
51
  rawStatus?: string;
51
52
  model: string;
@@ -54,6 +55,7 @@ export interface NormalizedVideoTask {
54
55
  export interface NormalizedVideoResult {
55
56
  ok: true;
56
57
  taskId: string;
58
+ videoId?: string;
57
59
  status: AgnesStatus;
58
60
  rawStatus?: string;
59
61
  model: string;
package/dist/index.d.ts CHANGED
@@ -29,6 +29,6 @@ export declare function createAgnesClient(config?: AgnesClientConfig): {
29
29
  };
30
30
  video: {
31
31
  generate: (options: import("./video/normalizeVideoRequest.js").VideoGenerateOptions) => Promise<import("./config.js").NormalizedVideoTask>;
32
- poll: (taskId: string, options?: import("./video/pollVideo.js").PollVideoOptions) => Promise<import("./config.js").NormalizedVideoResult>;
32
+ poll: (id: string, options?: import("./video/pollVideo.js").PollVideoOptions) => Promise<import("./config.js").NormalizedVideoResult>;
33
33
  };
34
34
  };
package/dist/index.js CHANGED
@@ -24,7 +24,7 @@ export function createAgnesClient(config = {}) {
24
24
  },
25
25
  video: {
26
26
  generate: (options) => generateVideo(options, config),
27
- poll: (taskId, options) => pollVideo(taskId, options, config),
27
+ poll: (id, options) => pollVideo(id, options, config),
28
28
  },
29
29
  };
30
30
  }
@@ -3,4 +3,5 @@ import { type VideoGenerateOptions } from "./normalizeVideoRequest.js";
3
3
  export declare function generateVideo(options: VideoGenerateOptions, config?: AgnesClientConfig): Promise<NormalizedVideoTask>;
4
4
  export declare function normalizeVideoTask(raw: unknown): NormalizedVideoTask;
5
5
  export declare function extractTaskId(record: Record<string, unknown>): string;
6
+ export declare function extractVideoId(record: Record<string, unknown>): string | undefined;
6
7
  export declare function normalizeStatus(rawStatus: string): "queued" | "in_progress" | "completed" | "failed";
@@ -42,10 +42,12 @@ async function resolveMediaInputs(inputs, ttl, config) {
42
42
  export function normalizeVideoTask(raw) {
43
43
  const record = ensureRecord(raw);
44
44
  const taskId = extractTaskId(record);
45
+ const videoId = extractVideoId(record);
45
46
  const rawStatus = typeof record.status === "string" ? record.status : "queued";
46
47
  return {
47
48
  ok: true,
48
49
  taskId,
50
+ videoId,
49
51
  status: normalizeStatus(rawStatus),
50
52
  rawStatus,
51
53
  model: typeof record.model === "string" ? record.model : "agnes-video-v2.0",
@@ -69,6 +71,13 @@ export function extractTaskId(record) {
69
71
  }
70
72
  return taskId;
71
73
  }
74
+ export function extractVideoId(record) {
75
+ if (typeof record.video_id === "string")
76
+ return record.video_id;
77
+ if (typeof record.id === "string" && record.id.startsWith("video_"))
78
+ return record.id;
79
+ return undefined;
80
+ }
72
81
  export function normalizeStatus(rawStatus) {
73
82
  if (rawStatus === "queued" || rawStatus === "in_progress" || rawStatus === "completed" || rawStatus === "failed") {
74
83
  return rawStatus;
@@ -3,5 +3,5 @@ export interface PollVideoOptions {
3
3
  intervalSeconds?: number;
4
4
  timeoutSeconds?: number;
5
5
  }
6
- export declare function pollVideo(taskId: string, options?: PollVideoOptions, config?: AgnesClientConfig): Promise<NormalizedVideoResult>;
6
+ export declare function pollVideo(id: string, options?: PollVideoOptions, config?: AgnesClientConfig): Promise<NormalizedVideoResult>;
7
7
  export declare function normalizeVideoResult(raw: unknown): NormalizedVideoResult;
@@ -1,20 +1,20 @@
1
1
  import { resolveConfig } from "../config.js";
2
2
  import { AgnesCliError } from "../errors.js";
3
3
  import { requestJson } from "../http/requestJson.js";
4
- import { extractTaskId, normalizeStatus } from "./generateVideo.js";
5
- export async function pollVideo(taskId, options = {}, config = {}) {
4
+ import { extractTaskId, extractVideoId, normalizeStatus } from "./generateVideo.js";
5
+ export async function pollVideo(id, options = {}, config = {}) {
6
6
  const resolved = resolveConfig(config);
7
7
  if (!resolved.apiKey) {
8
8
  throw new AgnesCliError("AUTH_MISSING", "AGNES_API_KEY is required for Agnes requests.");
9
9
  }
10
- const intervalMs = (options.intervalSeconds ?? 3) * 1000;
10
+ const intervalMs = (options.intervalSeconds ?? 5) * 1000;
11
11
  const timeoutMs = (options.timeoutSeconds ?? 600) * 1000;
12
12
  const started = Date.now();
13
13
  while (true) {
14
14
  if (Date.now() - started > timeoutMs) {
15
- throw new AgnesCliError("POLL_TIMEOUT", "Agnes video polling timed out.", { taskId, status: "timed_out" });
15
+ throw new AgnesCliError("POLL_TIMEOUT", "Agnes video polling timed out.", { id, status: "timed_out" });
16
16
  }
17
- const { response, raw } = await requestJson(resolved.fetchImpl, `${resolved.baseUrl}/videos/${taskId}`, {
17
+ const { response, raw } = await requestJson(resolved.fetchImpl, buildVideoPollUrl(resolved.baseUrl, id), {
18
18
  headers: {
19
19
  Authorization: `Bearer ${resolved.apiKey}`,
20
20
  },
@@ -22,13 +22,13 @@ export async function pollVideo(taskId, options = {}, config = {}) {
22
22
  networkMessage: "Agnes video poll request failed before a response was received.",
23
23
  });
24
24
  if (response.status === 404) {
25
- throw new AgnesCliError("TASK_NOT_FOUND", "Agnes video task was not found.", { taskId, status: "failed", raw });
25
+ throw new AgnesCliError("TASK_NOT_FOUND", "Agnes video task was not found.", { id, status: "failed", raw });
26
26
  }
27
27
  if (response.status === 503) {
28
- throw new AgnesCliError("SERVICE_BUSY", "Agnes video service is busy.", { taskId, status: "queued", raw });
28
+ throw new AgnesCliError("SERVICE_BUSY", "Agnes video service is busy.", { id, status: "queued", raw });
29
29
  }
30
30
  if (!response.ok) {
31
- throw new AgnesCliError("AGNES_REQUEST_FAILED", `Agnes video poll failed with HTTP ${response.status}.`, { taskId, status: "failed", raw });
31
+ throw new AgnesCliError("AGNES_REQUEST_FAILED", `Agnes video poll failed with HTTP ${response.status}.`, { id, status: "failed", raw });
32
32
  }
33
33
  const result = normalizeVideoResult(raw);
34
34
  if (result.status === "completed")
@@ -45,6 +45,7 @@ export function normalizeVideoResult(raw) {
45
45
  }
46
46
  const record = raw;
47
47
  const taskId = extractTaskId(record);
48
+ const videoId = extractVideoId(record);
48
49
  const rawStatus = typeof record.status === "string" ? record.status : "queued";
49
50
  const status = normalizeStatus(rawStatus);
50
51
  const videoUrl = extractVideoUrl(record);
@@ -54,6 +55,7 @@ export function normalizeVideoResult(raw) {
54
55
  return {
55
56
  ok: true,
56
57
  taskId,
58
+ videoId,
57
59
  status: status,
58
60
  rawStatus,
59
61
  model: typeof record.model === "string" ? record.model : "agnes-video-v2.0",
@@ -63,6 +65,14 @@ export function normalizeVideoResult(raw) {
63
65
  raw,
64
66
  };
65
67
  }
68
+ function buildVideoPollUrl(baseUrl, id) {
69
+ if (id.startsWith("task_")) {
70
+ return `${baseUrl.replace(/\/$/, "")}/videos/${encodeURIComponent(id)}`;
71
+ }
72
+ const url = new URL("/agnesapi", new URL(baseUrl));
73
+ url.searchParams.set("video_id", id);
74
+ return url.toString();
75
+ }
66
76
  function extractVideoUrl(record) {
67
77
  const candidates = [
68
78
  record.video_url,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agnes-ai-cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "CLI and JS API for Agnes text, image, and video workflows.",
5
5
  "type": "module",
6
6
  "bin": {