Add Veo 3 and Veo 3 Fast models (text-to-video + image-to-video) with
custom API integration using Kie's /api/v1/veo/ endpoints and numeric
successFlag polling. Also document Kie model integration SOP in CLAUDE.md.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Refactor executeSingleNode error paths to throw instead of setting global
isRunning/currentNodeIds state, which corrupted sibling nodes running in
parallel via Promise.allSettled
- Validate WaveSpeed providedPollUrl with SSRF check before use
- Sanitize WaveSpeed taskId in provider with path-traversal validation
- Revoke blob URLs (URL.revokeObjectURL) before replacing outputVideo to
prevent memory leaks from large video files
- Move pause edge cleanup to outer executeWorkflow loop
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add validateMediaUrl() utility to block private IPs, localhost, and
non-HTTP protocols before server-side fetches (with tests)
- URL-encode Kie taskId in poll URL to prevent injection
- Validate WaveSpeed modelId against path traversal in both route.ts
and wavespeed.ts provider
- Add 500MB Content-Length check before downloading media at all 3
fetch sites (Kie, WaveSpeed route, WaveSpeed provider)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update stale test mocks from currentNodeId to currentNodeIds in
AudioInputNode, EaseCurveNode, and VideoStitchNode tests. Replace
hard 401 return for missing FAL API key with console.warn, allowing
requests to proceed without auth (rate-limited) since
generateWithFal() already handles null keys gracefully.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add nano-banana-pro model to Kie provider with schema and image input key
- Reorder Kie generation to process dynamicInputs before fallback image
uploads, preventing double-uploads when schema-mapped connections exist
- Update test mocks for deduplicatedFetch, useProviderApiKeys, and static
handle changes across GenerateImageNode, GenerateVideoNode,
ModelParameters, and ModelSearchDialog tests
- Add test commands to CLAUDE.md
- Fix SplitGridSettingsModal grid preview count (5 → 6 options)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove 36 unsupported Kie.ai models (14 image, 22 video) and add 2 new
ones (kling-2.6/motion-control, topaz/video-upscale), bringing the total
to 22 models. Fix parameter schemas to match official Kie.ai docs:
seedream quality param, flux-2 input_urls, grok-imagine video mode/duration,
kling sound param, wan resolution param, and singular vs array image keys.
Remove dead Veo/Kontext/Runway helper functions and endpoint branching —
all remaining models use the standard createTask endpoint.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add ~38 new image/video models (Imagen 4, FLUX.2, Flux Kontext,
Grok Imagine, Ideogram, Qwen, Runway, Hailuo, Seedance variants,
Kling older, Wan older) with schemas and endpoint routing for
dedicated APIs (Flux Kontext, Runway). Add pageUrl to all Kie
models and update ModelSearchDialog to use it.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Added validation to ensure fal.ai API key is provided in requests, returning a 401 status with an appropriate error message if not configured.
- Updated related tests to reflect the new API key requirement and adjusted assertions for expected responses.
- Modified documentation to clarify that fal.ai API key is now mandatory for model access.
GPT Image 1.5 only supports 'aspect_ratio', not 'size'.
Remove stale 'size' values from old workflow data before sending.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix Kie.ai GPT Image 1.5 failing to retrieve output URL by parsing
resultJson as JSON string (was treated as object incorrectly)
- Add 1x5 grid option to SplitGridNode for vertical contact sheets
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update dynamicInputs type from Record<string, string> to Record<string, string | string[]> in 4 locations
- Fix getConnectedInputs to aggregate same-key values into arrays instead of overwriting
- Fix dynamicInputs.prompt access to handle array case
- Fix hasPrompt check in POST handler to handle array-typed prompt
- Update processedDynamicInputs type in both Replicate and fal blocks
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update dynamicInputs type from Record<string, string> to Record<string, string | string[]> in 4 locations
- Fix getConnectedInputs to aggregate same-key values into arrays instead of overwriting
- Fix dynamicInputs.prompt access to handle array case
- Fix hasPrompt check in POST handler to handle array-typed prompt
- Update processedDynamicInputs type in both Replicate and fal blocks
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Kie API returns HTTP 200 even on errors, with error code in the JSON body.
Now properly checks createResult.code !== 200 and returns the actual error
message from the API instead of generic "No task ID in response".
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Some Kie.ai models (like gpt-image/1.5-text-to-image) require certain
parameters to be present even if not user-specified (e.g., aspect_ratio,
quality). Add getKieModelDefaults() function that provides model-specific
defaults which are merged with user-provided parameters.
Also skip file logging on Vercel since filesystem is read-only.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use multipart/form-data for file upload with 'file' and 'uploadPath' fields
- Extract download URL from data.downloadUrl in upload response
- Wrap parameters in 'input' object for standard models
- Use flat structure with camelCase for Veo models
- Extract results from resultJson.resultUrls in poll response
Co-Authored-By: Claude <noreply@anthropic.com>
Add Kie.ai as a new provider for image and video generation:
Image models (8):
- z-image, seedream/4.5-text-to-image, seedream/4.5-edit
- nano-banana-pro, gpt-image/1.5-text-to-image, gpt-image/1.5-image-to-image
- google/nano-banana, google/nano-banana-edit
Video models (11):
- sora-2-text-to-video, sora-2-image-to-video
- sora-2-pro-text-to-video, sora-2-pro-image-to-video
- veo3_fast, veo3, bytedance/seedance-1.5-pro
- kling-2.6/text-to-video, kling-2.6/image-to-video
- wan/2-6-text-to-video, wan/2-6-image-to-video
Key changes:
- Add "kie" to ProviderType union
- Add generateWithKie() with image upload and task polling
- Add hardcoded model list and schemas (no discovery API)
- Update workflow store for API key handling
- Update UI components with Kie provider badge
Co-Authored-By: Claude <noreply@anthropic.com>
## Template Explorer Enhancements
- Add rich metadata and thumbnails for community workflows
- Create communityWorkflows.ts config for workflow metadata
- Reuse TemplateCard for community workflows with tag filtering
- Search now includes workflow descriptions
## Comment Navigation System
- Add comment navigation icon in header with unviewed count badge
- Navigate between nodes with comments using prev/next controls
- Tooltips show comment preview on hover
## Output Node Improvements
- Add custom filename and createDirectory options for output saves
- Remove default React Flow styling from output nodes
- Fix video output node connections
- Preserve node height on resize
## Image Handling Fixes
- Resolve image history race condition and duplicate images on save
- Preserve image history IDs when saving to new directory
- Verify outputImageRef matches selected history index on save
- Persist useExternalImageStorage setting in workflow config
- Paste images directly into selected imageInput nodes
## Model & Generation Fixes
- Use selectedModel.modelId for Gemini generation
- Return 200 with notFound flag instead of 404 for missing files
## Other
- Add git-lfs tracking for large workflow files
- Remove deprecated example workflows
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes issues with external provider models (e.g., seedream-4.5) where:
- Boolean/integer params with "image" in name were misclassified as image inputs
- Array params without items.type specification were incorrectly rejected
- Handle ID mismatch between node components (image-0) and store (image)
- dynamicInputs not passed to API in node regeneration code path
Changes:
- Update isImageInput() to check schema types, not just names
- Map both indexed (image-0) and legacy (image) handle IDs to schema names
- Add dynamicInputs to nanoBanana regeneration request body
- Add hidden backward-compat handles for edge routing
- Add comprehensive tests for schema classification and handle mapping
- Fix Toast test to use specific selector for close button
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create server.js with extended requestTimeout (10 min) for long-running fal.ai video generation
- Update package.json dev script to use custom server
- Add comments explaining why queue API is not used (file size limitations)
- Use WHATWG URL API instead of deprecated url.parse()
- Added support for long-running video generation using a queue system with a 10-minute timeout.
- Updated maxDuration constant to reflect the new timeout for video generation.
- Enhanced API request handling to accommodate video generation, including error handling and polling for completion.
- Updated model retrieval tests to reflect the inclusion of additional models and improved provider filtering.
- Modified component tests to track model usage and reflect changes in the UI for provider selection.
When providers like fal.ai or Replicate expect array parameters (e.g.,
image_urls), single values from dynamicInputs are now automatically
wrapped in arrays based on the OpenAPI schema's type property.
Changes:
- Add isArray field to ModelInput type for schema detection
- Update getFalInputMapping() to return schemaArrayParams
- Update getInputMappingFromSchema() to return schemaArrayParams
- Apply array wrapping in both fal.ai and Replicate handlers
- Add tests for array wrapping behavior
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix isImageInput() to use word-boundary checks instead of substring
matching, preventing num_images from being misclassified as image input
- Fix stale node data in workflow execution by getting fresh data from
store instead of using captured array references
- Add missing parameters to regenerateNode request bodies for both
nanoBanana and generateVideo nodes
- Update fal.ai schema fetch to use Model Search API endpoint
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Group file operations (save, open folder) together with subtle separator
- Separate settings button with visual spacing
- Add hover background states to icon buttons for better interactivity
- Improve unsaved indicator with ring outline for better visibility
- Use consistent padding (p-1.5) and rounded corners
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Updated .env.example to include new API keys for OpenAI, Replicate, and fal.ai.
- Modified API routes to prioritize user-provided API keys over environment variables for Gemini and OpenAI.
- Improved error messages for missing API keys to guide users on configuration.
- Enhanced ProjectSetupModal to support OpenAI provider and manage API key overrides.
- Updated workflow store to handle new provider settings and API key integration for OpenAI.
- Added functionality to auto-save generated images and videos to the specified directory.
- Introduced a model search dialog for selecting external models in GenerateImageNode and GenerateVideoNode.
- Updated node titles to reflect selected models dynamically.
- Improved parameter handling by expanding the ModelParameters component to notify parent nodes on schema load.
- Adjusted handle positions and styles for better alignment and visual consistency.
- Enhanced input validation and processing for dynamic inputs across the workflow.
- Render dynamic input handles from model schema (GenerateImage/VideoNode)
- Update connection validation with getHandleType() helper
- Add dynamicInputs to getConnectedInputs() return value
- Pass dynamicInputs through generation pipeline (workflowStore -> API)
- Update generateWithFal/Replicate to use dynamic inputs
- Process large images in dynamicInputs to URLs for external providers
- Support prompt from dynamicInputs when top-level prompt is empty
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add modelsFetchError state with retry button in GenerateImage/VideoNode
- Show clear errors when model list fails to load (API key issues, connection)
- Improve API route error messages to include model name
- Add rate limit handling (429) with user-friendly messages
- Parse provider-specific error responses for better detail
- Improve timeout message for video generation
- Include parameters in requestPayload for nanoBanana and generateVideo nodes
- Add logging for custom parameters in Replicate and fal.ai provider functions
- Parameters already spread via ...input.parameters in existing provider code
Extend /api/generate to support video output from Replicate and fal.ai:
- Detect video content type in Replicate response
- Handle fal.ai video.url field for video model responses
- Return video/videoUrl fields with contentType for videos
- Add generateVideo case to executeWorkflow and regenerateNode
- Handle large videos (>20MB) by returning URL directly
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Import uploadImageForUrl, shouldUseImageUrl, deleteImages from @/lib/images
- Process images for Replicate/fal providers before generation
- Small images (<256KB) use data URIs directly
- Large images converted to temporary URLs via /api/images/[id]
- Cleanup uploaded images in finally block (success or failure)
- Gemini path unchanged (handles base64 directly)
- Add image parameter to predictionInput when images array provided
- Log image input presence for debugging
- Uses 'image' param name (most common for img2img models)
Refactor generate API route to support multiple providers:
- Accept both legacy format and new format with selectedModel
- Route requests to Replicate, fal.ai, or Gemini based on provider
- Extract Gemini logic into generateWithGemini() helper function
- Add generateWithReplicate() and generateWithFal() server-side helpers
- Get provider API keys from request headers (X-Replicate-API-Key, X-Fal-API-Key)
- Preserve backward compatibility for existing Gemini-based workflows
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>