docs(03): update plans for separate image/video nodes
- Rename target from Generate to GenerateImage
- Filter model selector to image capabilities only (text-to-image, image-to-image)
- Note GenerateVideo node deferred to Phase 6
1. Rename file from NanoBananaNode.tsx to GenerateNode.tsx
1. Rename file from NanoBananaNode.tsx to GenerateImageNode.tsx
2. Rename component from NanoBananaNode to GenerateNode (keep function export name)
2. Rename component from NanoBananaNode to GenerateImageNode
3. Add model selector UI that shows:
- Provider dropdown (gemini, replicate, fal) - only show enabled providers
- Model dropdown (fetched from /api/models for selected provider)
- **Filter to image capabilities only**: text-to-image, image-to-image
- For Gemini, show existing hardcoded models (Nano Banana, Nano Banana Pro)
- For other providers, fetch models dynamically
- For other providers, fetch models dynamically with capability filter
4. When provider/model changes:
- Update node data with selectedModel: { provider, modelId, displayName }
@ -81,16 +84,16 @@ Output: Generate node component with provider/model dropdown, updated types, sto
5. Keep existing aspect ratio/resolution controls for Gemini models
- Hide them for non-Gemini models (parameters will come from provider schema later)
6. Update index.ts to export GenerateNode and alias it as NanoBananaNode for backward compatibility:
6. Update index.ts to export GenerateImageNode and alias as NanoBananaNode:
```typescript
export { GenerateNode } from "./GenerateNode";
export { GenerateNode as NanoBananaNode } from "./GenerateNode";
export { GenerateImageNode } from "./GenerateImageNode";
export { GenerateImageNode as NanoBananaNode } from "./GenerateImageNode";
```
WHY: The component rename reflects its new multi-provider purpose. The alias maintains backward compatibility with existing imports.
WHY: The component rename reflects its image-specific purpose. Video generation will be a separate GenerateVideoNode in Phase 6. The alias maintains backward compatibility.
</action>
<verify>npm run build succeeds, component renders in browser</verify>
<done>GenerateNode.tsx exists, shows provider selector, model dropdown fetches from API for non-Gemini providers</done>
<done>GenerateImageNode.tsx exists, shows provider selector, model dropdown shows only image-capable models</done>
</task>
<tasktype="auto">
@ -98,18 +101,18 @@ Output: Generate node component with provider/model dropdown, updated types, sto
Add provider-specific execution logic to the generate API route.
Add provider-specific execution logic to the generate API route for image generation.
Purpose: Enable the generate endpoint to route requests to the correct provider (Gemini, Replicate, fal.ai) based on the selected model.
Output: Updated /api/generate route that dispatches to provider-specific generation logic.
Purpose: Enable the generate endpoint to route requests to the correct provider (Gemini, Replicate, fal.ai) based on the selected model, filtering to image outputs only.
Output: Updated /api/generate route that dispatches to provider-specific image generation logic.
Note: Video generation will use a separate endpoint in Phase 6.
</objective>
<execution_context>
@ -59,12 +61,16 @@ Output: Updated /api/generate route that dispatches to provider-specific generat
3. Fetch output:
- Poll GET /predictions/{id} until status is "succeeded" or "failed"
- Convert output URL to base64 data URL
- Return in GenerationOutput format
- Return in GenerationOutput format with type: "image"
4. Filter to image models only:
- Only accept models with text-to-image or image-to-image capabilities
- Return error if video model passed (video generation is Phase 6)
WHY: Replicate requires polling for async predictions. The generate() method encapsulates this complexity.
WHY: Replicate requires polling for async predictions. The generate() method encapsulates this complexity. Image-only filter keeps this endpoint focused.
</action>
<verify>TypeScript compiles, generate() method exists and doesn't throw immediately</verify>
<done>Replicate provider has working generate() method that calls prediction API</done>
<done>Replicate provider has working generate() method that calls prediction API for image models</done>
</task>
<tasktype="auto">
@ -82,14 +88,18 @@ Output: Updated /api/generate route that dispatches to provider-specific generat
- API key optional but rate limited without it
3. Parse response:
- Extract image/video URL from response
- Extract image URL from response
- Convert to base64 data URL for consistency
- Handle different output formats (images array, video URL, etc.)
- Handle images array output format
4. Filter to image models only:
- Only accept models with text-to-image or image-to-image capabilities
- Return error if video model passed (video generation is Phase 6)
WHY: fal.ai's synchronous API is simpler than Replicate. The generate() method normalizes the response format.
WHY: fal.ai's synchronous API is simpler than Replicate. The generate() method normalizes the response format. Image-only filter keeps this endpoint focused.