From 5a81051e0fec2a401470913036825e864513d5ee Mon Sep 17 00:00:00 2001 From: Matt Miller Date: Mon, 14 Sep 2026 17:56:02 -0700 Subject: [PATCH] docs(comfy-router): narrow RunResult in the TypeScript snippets for SDK 0.3.0 `@comfyorg/sdk@0.3.0` makes `RunResult` a discriminated union, because the run route's `200` has two documented shapes: an `application/json` document and a `*/*` binary body, which is how a partner whose generation IS the response answers. Destructuring `data` straight off the result no longer compiles when a type argument is supplied: error TS2339: Property 'result' does not exist on type 'Uint8Array | Result'. Every TypeScript snippet on the Router model pages is written that way, as is the quickstart, so each one is a copy-paste that fails to build against the current SDK. The generated pages are fixed at the source: `typescriptSnippet` in `.github/scripts/snippets/gen-code-pages.ts` now assigns the result and narrows on `kind` before reading `data`. The 27 affected pages are regenerated output, not hand edits, and `--check --validate` reports all 204 fresh. The quickstart is hand-written and is patched directly. Its install line also pinned `@comfyorg/sdk@^0.1.9`, which on a `0.x` caret resolves below `0.2.0` and so never picked up either of the last two releases; now `^0.3.0`. The untyped snippets (`const { data } = await comfy.models.run(...)` with no type argument) still compile, since `data` is `unknown` either way, and are left alone. Not in this change: the binary models have more to say now than they used to. `elevenlabs/eleven_v3` and `elevenlabs/eleven_sfx_v2` answer with audio bytes, which 0.3.0 can finally return, and their pages still print the result as if it were a document. Teaching the generator to emit a binary branch for those models is worth its own pass. Co-Authored-By: Claude Opus 5 --- .github/scripts/snippets/gen-code-pages.ts | 5 +++-- .../flux-1-1-pro-ultra-image/code.mdx | 10 ++++++---- .../black-forest-labs/flux-1-kontext/code.mdx | 10 ++++++---- .../black-forest-labs/flux-3-video/code.mdx | 5 +++-- .../flux-video-upscale/code.mdx | 5 +++-- .../models/google/gemini/code.mdx | 20 +++++++++++-------- .../models/google/nano-banana-2-lite/code.mdx | 5 +++-- .../models/google/nano-banana-2/code.mdx | 5 +++-- .../models/google/nano-banana-pro/code.mdx | 5 +++-- .../models/ideogram/ideogram-v4/code.mdx | 5 +++-- .../models/wan/happyhorse-1-0-i2v/code.mdx | 5 +++-- .../models/wan/happyhorse-1-0-r2v/code.mdx | 5 +++-- .../models/wan/happyhorse-1-0-t2v/code.mdx | 5 +++-- .../wan/happyhorse-1-0-video-edit/code.mdx | 5 +++-- .../models/wan/happyhorse-1-1-i2v/code.mdx | 5 +++-- .../models/wan/happyhorse-1-1-r2v/code.mdx | 5 +++-- .../models/wan/happyhorse-1-1-t2v/code.mdx | 5 +++-- .../models/wan/wan2-5-i2v-preview/code.mdx | 5 +++-- .../models/wan/wan2-5-t2v-preview/code.mdx | 5 +++-- .../models/wan/wan2-6-i2v/code.mdx | 5 +++-- .../models/wan/wan2-6-r2v/code.mdx | 5 +++-- .../models/wan/wan2-6-t2v/code.mdx | 5 +++-- .../models/wan/wan2-7-i2v/code.mdx | 5 +++-- .../models/wan/wan2-7-r2v/code.mdx | 5 +++-- .../models/wan/wan2-7-t2v/code.mdx | 5 +++-- .../models/wan/wan2-7-videoedit/code.mdx | 5 +++-- .../models/wan/wan3-0-video-prime/code.mdx | 5 +++-- .../models/wan/wan3-0-video/code.mdx | 5 +++-- development/comfy-router/quickstart.mdx | 8 +++++--- 29 files changed, 104 insertions(+), 69 deletions(-) diff --git a/.github/scripts/snippets/gen-code-pages.ts b/.github/scripts/snippets/gen-code-pages.ts index 095399f30..6d2990544 100644 --- a/.github/scripts/snippets/gen-code-pages.ts +++ b/.github/scripts/snippets/gen-code-pages.ts @@ -334,11 +334,12 @@ function typescriptSnippet(model: string, example: Record, file ${reads ? `${reads}\n\n` : ""}// Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = ${tsResultType(resultPath)}; -const { data } = await comfy.models.run("${model}", { +const result = await comfy.models.run("${model}", { ${body} }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("${label}:", data${tsPath(resultPath)});`; +console.log("${label}:", result.data${tsPath(resultPath)});`; } function curlSnippet(model: string, example: Record, files: FileInput[]): string { diff --git a/development/comfy-router/models/black-forest-labs/flux-1-1-pro-ultra-image/code.mdx b/development/comfy-router/models/black-forest-labs/flux-1-1-pro-ultra-image/code.mdx index 591b6997c..b0bc8a7c9 100644 --- a/development/comfy-router/models/black-forest-labs/flux-1-1-pro-ultra-image/code.mdx +++ b/development/comfy-router/models/black-forest-labs/flux-1-1-pro-ultra-image/code.mdx @@ -47,13 +47,14 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { result: { sample: string } }; -const { data } = await comfy.models.run("bfl/flux-pro-1.1-ultra", { +const result = await comfy.models.run("bfl/flux-pro-1.1-ultra", { prompt: "a single red maple leaf on a plain white background, studio lighting", aspect_ratio: "16:9", raw: false, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("image:", data.result.sample); +console.log("image:", result.data.result.sample); ``` ```bash cURL @@ -249,13 +250,14 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { result: { sample: string } }; -const { data } = await comfy.models.run("bfl/flux-pro-1.1", { +const result = await comfy.models.run("bfl/flux-pro-1.1", { prompt: "a single red maple leaf on a plain white background, studio lighting", width: 1024, height: 768, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("image:", data.result.sample); +console.log("image:", result.data.result.sample); ``` ```bash cURL diff --git a/development/comfy-router/models/black-forest-labs/flux-1-kontext/code.mdx b/development/comfy-router/models/black-forest-labs/flux-1-kontext/code.mdx index 13ba6a06a..5df187f36 100644 --- a/development/comfy-router/models/black-forest-labs/flux-1-kontext/code.mdx +++ b/development/comfy-router/models/black-forest-labs/flux-1-kontext/code.mdx @@ -55,13 +55,14 @@ const inputImage = (await readFile("input.jpg")).toString("base64"); // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { result: { sample: string } }; -const { data } = await comfy.models.run("bfl/flux-kontext-pro", { +const result = await comfy.models.run("bfl/flux-kontext-pro", { prompt: "replace the background with a sunlit beach, keep the subject unchanged", input_image: inputImage, aspect_ratio: "1:1", }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("image:", data.result.sample); +console.log("image:", result.data.result.sample); ``` ```bash cURL @@ -269,13 +270,14 @@ const inputImage = (await readFile("input.jpg")).toString("base64"); // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { result: { sample: string } }; -const { data } = await comfy.models.run("bfl/flux-kontext-max", { +const result = await comfy.models.run("bfl/flux-kontext-max", { prompt: "replace the background with a sunlit beach, keep the subject unchanged", input_image: inputImage, aspect_ratio: "1:1", }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("image:", data.result.sample); +console.log("image:", result.data.result.sample); ``` ```bash cURL diff --git a/development/comfy-router/models/black-forest-labs/flux-3-video/code.mdx b/development/comfy-router/models/black-forest-labs/flux-3-video/code.mdx index 1200cb640..8e04834e3 100644 --- a/development/comfy-router/models/black-forest-labs/flux-3-video/code.mdx +++ b/development/comfy-router/models/black-forest-labs/flux-3-video/code.mdx @@ -45,15 +45,16 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { result: { sample: string } }; -const { data } = await comfy.models.run("bfl/flux-3-video", { +const result = await comfy.models.run("bfl/flux-3-video", { mode: "t2v", prompt: "a single red maple leaf falling onto still water, slow motion", duration: 5, aspect_ratio: "16:9", generate_audio: true, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.result.sample); +console.log("video:", result.data.result.sample); ``` ```bash cURL diff --git a/development/comfy-router/models/black-forest-labs/flux-video-upscale/code.mdx b/development/comfy-router/models/black-forest-labs/flux-video-upscale/code.mdx index f5312b4e3..38f9bce44 100644 --- a/development/comfy-router/models/black-forest-labs/flux-video-upscale/code.mdx +++ b/development/comfy-router/models/black-forest-labs/flux-video-upscale/code.mdx @@ -43,13 +43,14 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { result: { sample: string } }; -const { data } = await comfy.models.run("bfl/video-upscale-v1", { +const result = await comfy.models.run("bfl/video-upscale-v1", { input_video: "https://your-host.example/clip.mp4", upscale_factor: 2, creativity: 1, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.result.sample); +console.log("video:", result.data.result.sample); ``` ```bash cURL diff --git a/development/comfy-router/models/google/gemini/code.mdx b/development/comfy-router/models/google/gemini/code.mdx index a76548658..d999ff15a 100644 --- a/development/comfy-router/models/google/gemini/code.mdx +++ b/development/comfy-router/models/google/gemini/code.mdx @@ -58,7 +58,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { candidates: { content: { parts: { text: string }[] } }[] }; -const { data } = await comfy.models.run("vertexai/gemini-3.1-pro-preview", { +const result = await comfy.models.run("vertexai/gemini-3.1-pro-preview", { contents: [ { role: "user", @@ -74,8 +74,9 @@ const { data } = await comfy.models.run("vertexai/gemini-3.1-pro-preview maxOutputTokens: 256, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("text:", data.candidates[0].content.parts[0].text); +console.log("text:", result.data.candidates[0].content.parts[0].text); ``` ```bash cURL @@ -128,7 +129,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { candidates: { content: { parts: { text: string }[] } }[] }; -const { data } = await comfy.models.run("vertexai/gemini-3.5-flash", { +const result = await comfy.models.run("vertexai/gemini-3.5-flash", { contents: [ { role: "user", @@ -144,8 +145,9 @@ const { data } = await comfy.models.run("vertexai/gemini-3.5-flash", { maxOutputTokens: 256, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("text:", data.candidates[0].content.parts[0].text); +console.log("text:", result.data.candidates[0].content.parts[0].text); ``` ```bash cURL @@ -198,7 +200,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { candidates: { content: { parts: { text: string }[] } }[] }; -const { data } = await comfy.models.run("vertexai/gemini-2.5-pro", { +const result = await comfy.models.run("vertexai/gemini-2.5-pro", { contents: [ { role: "user", @@ -214,8 +216,9 @@ const { data } = await comfy.models.run("vertexai/gemini-2.5-pro", { maxOutputTokens: 256, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("text:", data.candidates[0].content.parts[0].text); +console.log("text:", result.data.candidates[0].content.parts[0].text); ``` ```bash cURL @@ -268,7 +271,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { candidates: { content: { parts: { text: string }[] } }[] }; -const { data } = await comfy.models.run("vertexai/gemini-2.5-flash", { +const result = await comfy.models.run("vertexai/gemini-2.5-flash", { contents: [ { role: "user", @@ -284,8 +287,9 @@ const { data } = await comfy.models.run("vertexai/gemini-2.5-flash", { maxOutputTokens: 256, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("text:", data.candidates[0].content.parts[0].text); +console.log("text:", result.data.candidates[0].content.parts[0].text); ``` ```bash cURL diff --git a/development/comfy-router/models/google/nano-banana-2-lite/code.mdx b/development/comfy-router/models/google/nano-banana-2-lite/code.mdx index 6bd7e0c62..dbec01a2c 100644 --- a/development/comfy-router/models/google/nano-banana-2-lite/code.mdx +++ b/development/comfy-router/models/google/nano-banana-2-lite/code.mdx @@ -56,7 +56,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { candidates: { content: { parts: { inlineData: { data: string } }[] } }[] }; -const { data } = await comfy.models.run("vertexai/gemini-3.1-flash-lite-image", { +const result = await comfy.models.run("vertexai/gemini-3.1-flash-lite-image", { contents: [ { role: "user", @@ -74,8 +74,9 @@ const { data } = await comfy.models.run("vertexai/gemini-3.1-flash-lite- }, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("image (base64):", data.candidates[0].content.parts[0].inlineData.data); +console.log("image (base64):", result.data.candidates[0].content.parts[0].inlineData.data); ``` ```bash cURL diff --git a/development/comfy-router/models/google/nano-banana-2/code.mdx b/development/comfy-router/models/google/nano-banana-2/code.mdx index 45949b621..4d620e943 100644 --- a/development/comfy-router/models/google/nano-banana-2/code.mdx +++ b/development/comfy-router/models/google/nano-banana-2/code.mdx @@ -56,7 +56,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { candidates: { content: { parts: { inlineData: { data: string } }[] } }[] }; -const { data } = await comfy.models.run("vertexai/gemini-3.1-flash-image", { +const result = await comfy.models.run("vertexai/gemini-3.1-flash-image", { contents: [ { role: "user", @@ -74,8 +74,9 @@ const { data } = await comfy.models.run("vertexai/gemini-3.1-flash-image }, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("image (base64):", data.candidates[0].content.parts[0].inlineData.data); +console.log("image (base64):", result.data.candidates[0].content.parts[0].inlineData.data); ``` ```bash cURL diff --git a/development/comfy-router/models/google/nano-banana-pro/code.mdx b/development/comfy-router/models/google/nano-banana-pro/code.mdx index ccc0be0f5..4eecb2c22 100644 --- a/development/comfy-router/models/google/nano-banana-pro/code.mdx +++ b/development/comfy-router/models/google/nano-banana-pro/code.mdx @@ -56,7 +56,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { candidates: { content: { parts: { inlineData: { data: string } }[] } }[] }; -const { data } = await comfy.models.run("vertexai/gemini-3-pro-image", { +const result = await comfy.models.run("vertexai/gemini-3-pro-image", { contents: [ { role: "user", @@ -74,8 +74,9 @@ const { data } = await comfy.models.run("vertexai/gemini-3-pro-image", { }, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("image (base64):", data.candidates[0].content.parts[0].inlineData.data); +console.log("image (base64):", result.data.candidates[0].content.parts[0].inlineData.data); ``` ```bash cURL diff --git a/development/comfy-router/models/ideogram/ideogram-v4/code.mdx b/development/comfy-router/models/ideogram/ideogram-v4/code.mdx index 6d4dae66d..071ce6423 100644 --- a/development/comfy-router/models/ideogram/ideogram-v4/code.mdx +++ b/development/comfy-router/models/ideogram/ideogram-v4/code.mdx @@ -43,13 +43,14 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { data: { url: string }[] }; -const { data } = await comfy.models.run("ideogram/ideogram-v4", { +const result = await comfy.models.run("ideogram/ideogram-v4", { text_prompt: "a single red maple leaf on a plain white background, studio lighting", resolution: "1024x1024", rendering_speed: "DEFAULT", }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("image:", data.data[0].url); +console.log("image:", result.data.data[0].url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/happyhorse-1-0-i2v/code.mdx b/development/comfy-router/models/wan/happyhorse-1-0-i2v/code.mdx index 51209d114..4a4bb9453 100644 --- a/development/comfy-router/models/wan/happyhorse-1-0-i2v/code.mdx +++ b/development/comfy-router/models/wan/happyhorse-1-0-i2v/code.mdx @@ -48,7 +48,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/happyhorse-1.0-i2v", { +const result = await comfy.models.run("wan/happyhorse-1.0-i2v", { input: { prompt: "the robot lowers its raised arm and steps toward the camera, the flat orange backdrop holds steady", img_url: "https://raw.githubusercontent.com/Comfy-Org/workflow_templates/main/input/pink_robot_front.png", @@ -58,8 +58,9 @@ const { data } = await comfy.models.run("wan/happyhorse-1.0-i2v", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/happyhorse-1-0-r2v/code.mdx b/development/comfy-router/models/wan/happyhorse-1-0-r2v/code.mdx index d007b6ad7..52fe1c3a9 100644 --- a/development/comfy-router/models/wan/happyhorse-1-0-r2v/code.mdx +++ b/development/comfy-router/models/wan/happyhorse-1-0-r2v/code.mdx @@ -53,7 +53,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/happyhorse-1.0-r2v", { +const result = await comfy.models.run("wan/happyhorse-1.0-r2v", { input: { prompt: "character1 walks in from the left, turns to the camera and waves, plain orange backdrop", media: [ @@ -68,8 +68,9 @@ const { data } = await comfy.models.run("wan/happyhorse-1.0-r2v", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/happyhorse-1-0-t2v/code.mdx b/development/comfy-router/models/wan/happyhorse-1-0-t2v/code.mdx index 2693fd44c..0b1b45c72 100644 --- a/development/comfy-router/models/wan/happyhorse-1-0-t2v/code.mdx +++ b/development/comfy-router/models/wan/happyhorse-1-0-t2v/code.mdx @@ -47,7 +47,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/happyhorse-1.0-t2v", { +const result = await comfy.models.run("wan/happyhorse-1.0-t2v", { input: { prompt: "a single red maple leaf falling onto still water, slow motion, shallow depth of field", }, @@ -56,8 +56,9 @@ const { data } = await comfy.models.run("wan/happyhorse-1.0-t2v", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/happyhorse-1-0-video-edit/code.mdx b/development/comfy-router/models/wan/happyhorse-1-0-video-edit/code.mdx index 2868ef7f4..52c5e7837 100644 --- a/development/comfy-router/models/wan/happyhorse-1-0-video-edit/code.mdx +++ b/development/comfy-router/models/wan/happyhorse-1-0-video-edit/code.mdx @@ -52,7 +52,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/happyhorse-1.0-video-edit", { +const result = await comfy.models.run("wan/happyhorse-1.0-video-edit", { input: { prompt: "restyle the clip as a hand-drawn ink sketch, keep the dancer's movement unchanged", media: [ @@ -66,8 +66,9 @@ const { data } = await comfy.models.run("wan/happyhorse-1.0-video-edit", resolution: "720P", }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/happyhorse-1-1-i2v/code.mdx b/development/comfy-router/models/wan/happyhorse-1-1-i2v/code.mdx index 9d3fce0bd..ac5786f68 100644 --- a/development/comfy-router/models/wan/happyhorse-1-1-i2v/code.mdx +++ b/development/comfy-router/models/wan/happyhorse-1-1-i2v/code.mdx @@ -48,7 +48,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/happyhorse-1.1-i2v", { +const result = await comfy.models.run("wan/happyhorse-1.1-i2v", { input: { prompt: "the robot lowers its raised arm and steps toward the camera, the flat orange backdrop holds steady", img_url: "https://raw.githubusercontent.com/Comfy-Org/workflow_templates/main/input/pink_robot_front.png", @@ -58,8 +58,9 @@ const { data } = await comfy.models.run("wan/happyhorse-1.1-i2v", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/happyhorse-1-1-r2v/code.mdx b/development/comfy-router/models/wan/happyhorse-1-1-r2v/code.mdx index 37765d89c..7fc963a59 100644 --- a/development/comfy-router/models/wan/happyhorse-1-1-r2v/code.mdx +++ b/development/comfy-router/models/wan/happyhorse-1-1-r2v/code.mdx @@ -53,7 +53,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/happyhorse-1.1-r2v", { +const result = await comfy.models.run("wan/happyhorse-1.1-r2v", { input: { prompt: "character1 walks in from the left, turns to the camera and waves, plain orange backdrop", media: [ @@ -68,8 +68,9 @@ const { data } = await comfy.models.run("wan/happyhorse-1.1-r2v", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/happyhorse-1-1-t2v/code.mdx b/development/comfy-router/models/wan/happyhorse-1-1-t2v/code.mdx index 4b8d24b73..02775870d 100644 --- a/development/comfy-router/models/wan/happyhorse-1-1-t2v/code.mdx +++ b/development/comfy-router/models/wan/happyhorse-1-1-t2v/code.mdx @@ -47,7 +47,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/happyhorse-1.1-t2v", { +const result = await comfy.models.run("wan/happyhorse-1.1-t2v", { input: { prompt: "a single red maple leaf falling onto still water, slow motion, shallow depth of field", }, @@ -56,8 +56,9 @@ const { data } = await comfy.models.run("wan/happyhorse-1.1-t2v", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/wan2-5-i2v-preview/code.mdx b/development/comfy-router/models/wan/wan2-5-i2v-preview/code.mdx index 98887e134..9369d77cd 100644 --- a/development/comfy-router/models/wan/wan2-5-i2v-preview/code.mdx +++ b/development/comfy-router/models/wan/wan2-5-i2v-preview/code.mdx @@ -48,7 +48,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/wan2.5-i2v-preview", { +const result = await comfy.models.run("wan/wan2.5-i2v-preview", { input: { prompt: "the robot lowers its raised arm and steps toward the camera, the flat orange backdrop holds steady", img_url: "https://raw.githubusercontent.com/Comfy-Org/workflow_templates/main/input/pink_robot_front.png", @@ -58,8 +58,9 @@ const { data } = await comfy.models.run("wan/wan2.5-i2v-preview", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/wan2-5-t2v-preview/code.mdx b/development/comfy-router/models/wan/wan2-5-t2v-preview/code.mdx index 75eb883e9..e41df988b 100644 --- a/development/comfy-router/models/wan/wan2-5-t2v-preview/code.mdx +++ b/development/comfy-router/models/wan/wan2-5-t2v-preview/code.mdx @@ -47,7 +47,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/wan2.5-t2v-preview", { +const result = await comfy.models.run("wan/wan2.5-t2v-preview", { input: { prompt: "a single red maple leaf falling onto still water, slow motion, shallow depth of field", }, @@ -56,8 +56,9 @@ const { data } = await comfy.models.run("wan/wan2.5-t2v-preview", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/wan2-6-i2v/code.mdx b/development/comfy-router/models/wan/wan2-6-i2v/code.mdx index bdfa27f15..0b41c3a81 100644 --- a/development/comfy-router/models/wan/wan2-6-i2v/code.mdx +++ b/development/comfy-router/models/wan/wan2-6-i2v/code.mdx @@ -48,7 +48,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/wan2.6-i2v", { +const result = await comfy.models.run("wan/wan2.6-i2v", { input: { prompt: "the robot lowers its raised arm and steps toward the camera, the flat orange backdrop holds steady", img_url: "https://raw.githubusercontent.com/Comfy-Org/workflow_templates/main/input/pink_robot_front.png", @@ -58,8 +58,9 @@ const { data } = await comfy.models.run("wan/wan2.6-i2v", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/wan2-6-r2v/code.mdx b/development/comfy-router/models/wan/wan2-6-r2v/code.mdx index a6b29779f..8ee6579f4 100644 --- a/development/comfy-router/models/wan/wan2-6-r2v/code.mdx +++ b/development/comfy-router/models/wan/wan2-6-r2v/code.mdx @@ -48,7 +48,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/wan2.6-r2v", { +const result = await comfy.models.run("wan/wan2.6-r2v", { input: { prompt: "character1 walks in from the left, turns to the camera and waves, plain orange backdrop", reference_video_urls: ["https://raw.githubusercontent.com/Comfy-Org/workflow_templates/main/input/street_dancer.mp4"], @@ -58,8 +58,9 @@ const { data } = await comfy.models.run("wan/wan2.6-r2v", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/wan2-6-t2v/code.mdx b/development/comfy-router/models/wan/wan2-6-t2v/code.mdx index 80bd93dd1..04517af50 100644 --- a/development/comfy-router/models/wan/wan2-6-t2v/code.mdx +++ b/development/comfy-router/models/wan/wan2-6-t2v/code.mdx @@ -47,7 +47,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/wan2.6-t2v", { +const result = await comfy.models.run("wan/wan2.6-t2v", { input: { prompt: "a single red maple leaf falling onto still water, slow motion, shallow depth of field", }, @@ -56,8 +56,9 @@ const { data } = await comfy.models.run("wan/wan2.6-t2v", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/wan2-7-i2v/code.mdx b/development/comfy-router/models/wan/wan2-7-i2v/code.mdx index e38a8bd1d..6d93bb098 100644 --- a/development/comfy-router/models/wan/wan2-7-i2v/code.mdx +++ b/development/comfy-router/models/wan/wan2-7-i2v/code.mdx @@ -53,7 +53,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/wan2.7-i2v", { +const result = await comfy.models.run("wan/wan2.7-i2v", { input: { prompt: "the robot lowers its raised arm and steps toward the camera, the flat orange backdrop holds steady", media: [ @@ -68,8 +68,9 @@ const { data } = await comfy.models.run("wan/wan2.7-i2v", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/wan2-7-r2v/code.mdx b/development/comfy-router/models/wan/wan2-7-r2v/code.mdx index bfdffcab4..d4f87cfc5 100644 --- a/development/comfy-router/models/wan/wan2-7-r2v/code.mdx +++ b/development/comfy-router/models/wan/wan2-7-r2v/code.mdx @@ -53,7 +53,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/wan2.7-r2v", { +const result = await comfy.models.run("wan/wan2.7-r2v", { input: { prompt: "character1 walks in from the left, turns to the camera and waves, plain orange backdrop", media: [ @@ -68,8 +68,9 @@ const { data } = await comfy.models.run("wan/wan2.7-r2v", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/wan2-7-t2v/code.mdx b/development/comfy-router/models/wan/wan2-7-t2v/code.mdx index e16b0c3b0..119c32b0a 100644 --- a/development/comfy-router/models/wan/wan2-7-t2v/code.mdx +++ b/development/comfy-router/models/wan/wan2-7-t2v/code.mdx @@ -47,7 +47,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/wan2.7-t2v", { +const result = await comfy.models.run("wan/wan2.7-t2v", { input: { prompt: "a single red maple leaf falling onto still water, slow motion, shallow depth of field", }, @@ -56,8 +56,9 @@ const { data } = await comfy.models.run("wan/wan2.7-t2v", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/wan2-7-videoedit/code.mdx b/development/comfy-router/models/wan/wan2-7-videoedit/code.mdx index 7ed0970f2..c58185587 100644 --- a/development/comfy-router/models/wan/wan2-7-videoedit/code.mdx +++ b/development/comfy-router/models/wan/wan2-7-videoedit/code.mdx @@ -53,7 +53,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/wan2.7-videoedit", { +const result = await comfy.models.run("wan/wan2.7-videoedit", { input: { prompt: "restyle the clip as a hand-drawn ink sketch, keep the dancer's movement unchanged", media: [ @@ -68,8 +68,9 @@ const { data } = await comfy.models.run("wan/wan2.7-videoedit", { audio_setting: "origin", }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/wan3-0-video-prime/code.mdx b/development/comfy-router/models/wan/wan3-0-video-prime/code.mdx index ecdd1bbbe..33cd6b95d 100644 --- a/development/comfy-router/models/wan/wan3-0-video-prime/code.mdx +++ b/development/comfy-router/models/wan/wan3-0-video-prime/code.mdx @@ -47,7 +47,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/wan3.0-video-prime", { +const result = await comfy.models.run("wan/wan3.0-video-prime", { input: { prompt: "a single red maple leaf falling onto still water, slow motion, shallow depth of field", }, @@ -56,8 +56,9 @@ const { data } = await comfy.models.run("wan/wan3.0-video-prime", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/models/wan/wan3-0-video/code.mdx b/development/comfy-router/models/wan/wan3-0-video/code.mdx index f9be9ce0a..89870e026 100644 --- a/development/comfy-router/models/wan/wan3-0-video/code.mdx +++ b/development/comfy-router/models/wan/wan3-0-video/code.mdx @@ -53,7 +53,7 @@ import { comfy } from "@comfyorg/sdk"; // Reads COMFY_API_KEY from the environment. // The SDK automatically creates an idempotency key and reuses it for automatic retries. type Result = { output: { video_url: string } }; -const { data } = await comfy.models.run("wan/wan3.0-video", { +const result = await comfy.models.run("wan/wan3.0-video", { input: { prompt: "the robot lowers its raised arm and steps toward the camera, the flat orange backdrop holds steady", media: [ @@ -68,8 +68,9 @@ const { data } = await comfy.models.run("wan/wan3.0-video", { duration: 5, }, }); +if (result.kind !== "json") throw new Error("expected a JSON result"); -console.log("video:", data.output.video_url); +console.log("video:", result.data.output.video_url); ``` ```bash cURL diff --git a/development/comfy-router/quickstart.mdx b/development/comfy-router/quickstart.mdx index 2a86287fd..492fde4e3 100644 --- a/development/comfy-router/quickstart.mdx +++ b/development/comfy-router/quickstart.mdx @@ -68,7 +68,7 @@ Comfy Router lets you call partner models through `https://api.comfy.org` with o ```typescript TypeScript // Node.js 22+ - // Install: npm install @comfyorg/sdk@^0.1.9 --save-dev tsx + // Install: npm install @comfyorg/sdk@^0.3.0 --save-dev tsx // Save as quickstart.mts, then run: npx tsx quickstart.mts import { comfy } from "@comfyorg/sdk"; @@ -78,13 +78,15 @@ Comfy Router lets you call partner models through `https://api.comfy.org` with o const idempotencyKey = process.env.COMFY_REQUEST_KEY; if (!idempotencyKey) throw new Error("Set COMFY_REQUEST_KEY first."); - const { data } = await comfy.models.run( + const result = await comfy.models.run( "bfl/flux-2-pro", { prompt: "a red teapot on a windowsill, morning light" }, { idempotencyKey, timeoutMs: 660_000 }, ); + // Some models answer with the generated file itself rather than JSON. + if (result.kind !== "json") throw new Error("expected a JSON result"); - console.log("image:", data.result.sample); + console.log("image:", result.data.result.sample); ```