Security & API route fixes:
- Remove API key query param support in fal/models route to prevent credential leakage
- Fix MIME type fallback in save-generation route (now uses prefix-based fallback: image/* -> png, video/* -> mp4, unknown -> bin)
- Add timeout (60s) and size limits (500MB) for remote fetch in save-generation route using AbortController
CSS fix:
- Consolidate duplicate :root blocks in globals.css
- Change handle selector from data-handletype="prompt" to data-handletype="text"
- Update --handle-color-text CSS variable from #a3a3a3 to #3b82f6
Test file global mock isolation:
- Fix useAnnotationStore mock to support Zustand selector pattern
- Use vi.stubGlobal() instead of direct global assignments to prevent test leakage
- Restore global.Image in afterAll hook in AnnotationModal.test.tsx
- Wrap async Done assertion in waitFor() in AnnotationModal.test.tsx
- Use idiomatic fireEvent.dragOver() in AnnotationNode.test.tsx
- Fix global.confirm stub with proper beforeAll/afterAll lifecycle in CostDialog.test.tsx
- Import ReactNode type properly in EdgeToolbar.test.tsx
- Update save-generation route test to expect AbortController signal in fetch call
- Add Multi-Provider Support (Beta) section for Replicate and fal.ai
- Update Tech Stack and Environment Variables with new providers
- Add docs link to welcome modal (https://node-banana-docs.vercel.app/)
- Remove debug console.log statements from gridSplitter and WorkflowCanvas
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.
- Image data flow through node chains (imageInput, annotation, nanoBanana)
- Text data flow through node chains (prompt, llmGenerate)
- Dynamic inputs from schema-mapped connections
- State updates during execution (status, outputImage)
- Mixed image and text data flow
The open project button was only visible for unsaved projects. Now it
displays in both states so users can always load a different project.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
- Add provider icons (Gemini, Replicate, fal.ai) as filter buttons
- Replace dropdown with horizontal icon button group
- Add green badge color for Gemini provider
- Add 'Recently Used' section at top of model list
- Filter recent models by capability (image/video)
- Show max 4 recent models with cover images
- Track model usage via trackModelUsage on selection
- Add getProviderDisplayName helper for consistent naming
- Add GEMINI_IMAGE_MODELS constant with nano-banana and nano-banana-pro
- Update GET handler to include Gemini models in response
- Support provider=gemini filter (returns only Gemini models)
- Gemini models appear first in 'all providers' results
- No API key needed for Gemini (always available)
Create api.ts with GenerateRequest, GenerateResponse, LLMGenerateRequest,
LLMGenerateResponse. Move RecentModel to providers.ts. Convert index.ts
to pure re-export hub with no type definitions.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create models.ts with AspectRatio, Resolution, ModelType.
Create workflow.ts with WorkflowEdge, WorkflowEdgeData, WorkflowSaveConfig,
WorkflowCostData, NodeGroup, GroupColor. Update nodes.ts to import from
domain files instead of index.ts to avoid circular dependencies.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add RecentModel interface to types/index.ts
- Add localStorage helpers: getRecentModels, saveRecentModels, MAX_RECENT_MODELS
- Add recentModels state to workflowStore (initialized from localStorage)
- Add trackModelUsage action to track model usage with timestamps
Create providers.ts with ProviderType, SelectedModel, ProviderConfig,
ProviderSettings, LLMProvider, and LLMModelType. Update index.ts to
re-export from providers.ts and import types for internal use.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace position-based sampling hash with MD5 in imageStorage.ts
- Add computeContentHash helper function
- Consistent with save-generation API (Phase 13 decision)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add tests verifying the parameters field (UI settings) is passed to
provider APIs:
- Replicate: parameters passed to prediction input
- Replicate: dynamicInputs take precedence when merging
- fal.ai: parameters passed to request body
- fal.ai: dynamicInputs take precedence when merging
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive tests for dynamic input handles:
- Multiple image handles for multi-frame video models
- Placeholder handles with dimmed opacity
- Handle ordering (images before text)
- Gap spacing between handle groups
- Schema integration tests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive tests for dynamic input handles:
- Multiple image handles with schema-name attributes
- Multiple text handles with schema-name attributes
- Placeholder handle variations with dimmed opacity
- Handle ordering (images before text)
- Gap spacing between handle groups
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive tests for /api/models route covering:
- Basic functionality: fal.ai without key, both providers with keys
- Provider filtering by query param
- Capabilities filtering
- Search query param (client-side for Replicate, server-side for fal.ai)
- Caching behavior: cache hits, cache misses, refresh bypass
- Error handling: partial provider failures, all providers failing
- Pagination for both Replicate and fal.ai (max 15 pages)
- Capability inference for Replicate models (video keywords, i2v keywords)
- fal.ai category mapping to ModelCapability
- Model sorting by provider then name
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive tests for /api/generate fal.ai path:
- Image generation success (images array response)
- Video generation success (video object response)
- Works without API key (unauthenticated allowed)
- Rate limit (429) handling with and without key
- Various response formats (image, images, video, output)
- Large video (>20MB) returns URL instead of base64
- Empty dynamicInputs values are filtered
- Dynamic inputs passed to fal.ai request
- Environment variable API key fallback
- Error response formats (error.message, detail array)
- No media URL in response handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive tests for /api/generate Replicate path:
- Image generation success with API key header
- Video generation success
- 401 when API key missing
- Rate limit (429) handling
- Prediction failure handling
- Prediction timeout (5 min max)
- Polling for prediction completion
- Large video (>20MB) returns URL instead of base64
- Dynamic inputs passed to prediction
- Environment variable API key fallback
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add tests for input validation and edge cases:
- Reject requests with no prompt, images, or dynamic inputs
- Accept image-to-image (images only, no prompt)
- Accept dynamicInputs with prompt, image frames, and image_url
- Handle multiple images in request
Add provider routing tests:
- Route to Gemini when no selectedModel provided
- Route to Gemini when selectedModel.provider is gemini
- Return 401 for Replicate without API key
Add response handling tests:
- Verify proper response structure
- Handle default MIME type fallback
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive tests for /api/generate route covering Gemini path:
- Success with prompt only and with images
- Config options (aspectRatio, resolution, googleSearch)
- Model mapping (nano-banana, nano-banana-pro)
- API key handling (env var vs header)
- Error cases (missing key, rate limits, no candidates, text-only response)
- MIME type extraction from data URLs
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tests Google/Gemini provider path covering success, validation, rate limits,
and API error handling. Uses vi.hoisted for proper mock class constructor.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
GroupsOverlay tests (24 tests):
- Test empty state rendering (no groups)
- Test group background rendering in ViewportPortal
- Test position, size, and color application
- Test group controls header with name display
- Test name editing (click, Enter, Escape, blur)
- Test lock/unlock toggle functionality
- Test color picker display and color selection
- Test delete group functionality
- Test multiple groups rendering
ModelParameters tests (30 tests):
- Test initial rendering (Gemini bypass, empty modelId)
- Test loading state and schema fetching
- Test error handling (fetch failure, network error)
- Test empty schema handling (component hides)
- Test collapse/expand toggle functionality
- Test parameter count display
- Test string input rendering and onChange
- Test number input with min/max validation
- Test integer validation (decimal error)
- Test boolean checkbox with schema defaults
- Test enum/select rendering with options
- Test parameter name formatting (snake_case to Title)
- Test API key headers in fetch requests
- Test onInputsLoaded callback
- Test multiple parameter types rendering
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Test empty state rendering (returns null when no history)
- Test trigger button with count badge and title
- Test fan open/close toggle functionality
- Test max 10 items in fan view with overflow indicator
- Test sidebar display with all history items
- Test Clear All functionality calling clearGlobalHistory
- Test model display (Pro vs Standard labels)
- Test prompt display with truncation and empty state
- Test drag and drop with proper data transfer
- Test relative time formatting (just now, minutes, hours)
- Test image thumbnail rendering in fan and sidebar
- Test keyboard navigation (Escape to close)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add QuickstartTemplatesView tests for preset and community workflow loading
- Add PromptWorkflowView tests for prompt input, validation, and generation
- Add QuickstartBackButton tests for click behavior and disabled state
- Mock fetch for template and workflow APIs
- Test error handling and loading states
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add WelcomeModal tests for rendering, navigation, file loading, and view transitions
- Add QuickstartInitialView tests for option buttons, external links, and accessibility
- Mock fetch for community workflows API and getAllPresets template function
- Test file input handling with valid/invalid workflow files
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Test visibility (render/not render based on isOpen)
- Test textarea with initial prompt value and typing updates
- Test Submit button calls onSubmit with updated prompt
- Test Cancel button behavior with/without unsaved changes
- Test unsaved changes confirmation dialog
- Test Escape key and backdrop click behaviors
- Test font size dropdown persistence with localStorage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ProjectSetupModal tests:
- Add tests for visibility and tab navigation
- Add tests for new project vs settings mode
- Add tests for form validation (name, directory)
- Add tests for save/create behavior with directory validation
- Add tests for browse directory functionality
- Add tests for keyboard shortcuts (Enter, Escape)
- Add tests for Providers tab API key inputs
CostDialog tests:
- Add tests for basic rendering and sections
- Add tests for cost display formatting
- Add tests for per-model cost breakdown
- Add tests for empty state handling
- Add tests for reset costs functionality
- Add tests for close behavior
- Add tests for pricing reference display
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add tests for visibility (isOpen, modal count registration)
- Add tests for search functionality (debounced search, auto-focus)
- Add tests for provider filter (dropdown, API filtering)
- Add tests for capability filter (image vs video filtering)
- Add tests for model card rendering (name, description, badges)
- Add tests for model selection (callback mode, create node mode)
- Add tests for close behavior (button, Escape, backdrop click)
- Add tests for loading, error, and empty states
- Add tests for API headers with provider keys
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Toast tests:
- Add tests for basic rendering (message, close button)
- Add tests for type styling (info, success, warning, error)
- Add tests for type icons
- Add tests for close button functionality
- Add tests for auto-hide after 4 seconds
- Add tests for persistent toast behavior
- Add tests for details section (collapsed/expanded states)
- Add tests for useToast store (show/hide)
CostIndicator tests:
- Add tests for basic rendering (hidden when no nodes/costs)
- Add tests for zero cost display
- Add tests for non-zero cost formatting
- Add tests for CostDialog opening/closing
- Add tests for cost updates when nodes change
- Add tests for splitGrid node cost calculation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add tests for basic rendering (position, header, shortcuts)
- Add tests for node type filtering by handle type (source/target)
- Add tests for menu item click behavior
- Add tests for keyboard navigation (arrows, enter, escape)
- Add tests for click outside closing
- Add tests for mouse hover highlighting
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
EditableEdge.test.tsx (17 tests):
- Basic rendering with path and interaction layer
- Edge colors for image, prompt, and pause states
- Pause indicator visibility
- Draggable handles in angular mode
- Selection state opacity
- Loading animation for target node
ReferenceEdge.test.tsx (13 tests):
- Basic rendering with dashed style
- Gray color gradient
- No interactive elements (read-only)
- Selection state opacity
- Connection to source and target nodes
EdgeToolbar.test.tsx (13 tests):
- Visibility based on edge selection
- Pause toggle button with correct icons
- Delete button functionality
- Toolbar positioning
- Button styling for pause states
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>