Browse Source

Merge pull request #117 from shrimbly/develop

Seedance 2 I2V: expose all media inputs
handoff-20260429-1057
Willie 3 months ago
committed by GitHub
parent
commit
6179f0bb1f
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 10
      CHANGELOG.md
  2. 2
      package.json
  3. 7
      src/app/api/generate/providers/kie.ts
  4. 12
      src/app/api/models/[modelId]/route.ts

10
CHANGELOG.md

@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased] ## [Unreleased]
## [1.6.0] - 2026-04-21
### Added
- **Seedance 2 I2V: richer media inputs** — The ByteDance Seedance 2.0 and 2.0 Fast image-to-video nodes now expose Last Frame, Reference Images (up to 9), Reference Videos (up to 3), and Reference Audio (up to 3) handles alongside First Frame. Handle descriptions document the First/Last Frame vs Reference Images mutual-exclusivity rule.
### Fixed
- **Seedance 2 I2V: reference-only runs no longer rejected** — When connecting images only to Reference Images, the request no longer duplicates them into `first_frame_url`, which Kie was rejecting as a mutually-exclusive combination.
## [1.5.0] - 2026-04-20 ## [1.5.0] - 2026-04-20
### Added ### Added

2
package.json

@ -1,6 +1,6 @@
{ {
"name": "node-banana", "name": "node-banana",
"version": "1.5.0", "version": "1.6.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "node server.js", "dev": "node server.js",

7
src/app/api/generate/providers/kie.ts

@ -624,9 +624,12 @@ export async function submitKieTask(
} }
} }
// Handle image inputs (fallback - only if dynamicInputs didn't already set the image key) // Handle image inputs (fallback - only if dynamicInputs didn't already handle any image key).
// If the schema-driven dynamic inputs already placed images into specific fields
// (e.g. reference_image_urls), don't also populate the default key — some models
// treat these fields as mutually exclusive and reject the request.
const imageKey = getKieImageInputKey(modelId); const imageKey = getKieImageInputKey(modelId);
if (input.images && input.images.length > 0 && !handledImageKeys.has(imageKey)) { if (input.images && input.images.length > 0 && handledImageKeys.size === 0) {
const imageUrls: string[] = []; const imageUrls: string[] = [];
for (const image of input.images) { for (const image of input.images) {
if (image.startsWith("http")) { if (image.startsWith("http")) {

12
src/app/api/models/[modelId]/route.ts

@ -881,7 +881,11 @@ function getKieSchema(modelId: string): ExtractedSchema {
], ],
inputs: [ inputs: [
{ name: "prompt", type: "text", required: false, label: "Prompt" }, { name: "prompt", type: "text", required: false, label: "Prompt" },
{ name: "first_frame_url", type: "image", required: true, label: "Image" }, { name: "first_frame_url", type: "image", required: false, label: "First Frame", description: "Starting frame. Mutually exclusive with Reference Images." },
{ name: "last_frame_url", type: "image", required: false, label: "Last Frame", description: "Optional end frame — interpolates from First to Last. Mutually exclusive with Reference Images." },
{ name: "reference_image_urls", type: "image", required: false, isArray: true, label: "Reference Images", description: "Up to 9 reference images for style/subject guidance. Mutually exclusive with First/Last Frame." },
{ name: "reference_video_urls", type: "image", required: false, isArray: true, label: "Reference Videos", description: "Up to 3 reference videos (accepts video data URLs over the image handle)." },
{ name: "reference_audio_urls", type: "audio", required: false, isArray: true, label: "Reference Audio", description: "Up to 3 reference audio clips." },
], ],
}, },
"bytedance/seedance-2-fast/text-to-video": { "bytedance/seedance-2-fast/text-to-video": {
@ -906,7 +910,11 @@ function getKieSchema(modelId: string): ExtractedSchema {
], ],
inputs: [ inputs: [
{ name: "prompt", type: "text", required: false, label: "Prompt" }, { name: "prompt", type: "text", required: false, label: "Prompt" },
{ name: "first_frame_url", type: "image", required: true, label: "Image" }, { name: "first_frame_url", type: "image", required: false, label: "First Frame", description: "Starting frame. Mutually exclusive with Reference Images." },
{ name: "last_frame_url", type: "image", required: false, label: "Last Frame", description: "Optional end frame — interpolates from First to Last. Mutually exclusive with Reference Images." },
{ name: "reference_image_urls", type: "image", required: false, isArray: true, label: "Reference Images", description: "Up to 9 reference images for style/subject guidance. Mutually exclusive with First/Last Frame." },
{ name: "reference_video_urls", type: "image", required: false, isArray: true, label: "Reference Videos", description: "Up to 3 reference videos (accepts video data URLs over the image handle)." },
{ name: "reference_audio_urls", type: "audio", required: false, isArray: true, label: "Reference Audio", description: "Up to 3 reference audio clips." },
], ],
}, },
"grok-imagine/text-to-video": { "grok-imagine/text-to-video": {

Loading…
Cancel
Save