You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

5.9 KiB

phase plan type
03-generate-node-refactor 2 execute
Add provider-specific execution logic to the generate API route.

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.

<execution_context> ~/.claude/get-shit-done/workflows/execute-phase.md ~/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md

Prior plan context:

@.planning/phases/03-generate-node-refactor/03-01-SUMMARY.md

Key source files:

@src/app/api/generate/route.ts @src/lib/providers/types.ts @src/lib/providers/replicate.ts @src/lib/providers/fal.ts @src/lib/providers/index.ts

Tech stack available: ProviderInterface with generate() method, provider registry Established patterns: API routes return { success, data/error }, provider self-registration Constraining decisions:

  • Gemini generation logic already works, preserve it
  • Provider implementations have generate() method defined in ProviderInterface
Task 1: Implement generate() method in Replicate provider src/lib/providers/replicate.ts 1. Implement the generate() method that currently throws "not implemented": - Accept GenerationInput with model, prompt, images, parameters - Call Replicate's prediction API: POST https://api.replicate.com/v1/predictions - Handle input format: { version: model.id, input: { prompt, image?, ...parameters } } - Poll for completion (Replicate is async) or use webhook pattern - Return GenerationOutput with image/video data
  1. Handle image input:

    • If images provided, check if Replicate model expects URLs
    • For now, skip image input (Phase 5 adds image URL server)
    • Log warning if images provided but skipped
  2. Fetch output:

    • Poll GET /predictions/{id} until status is "succeeded" or "failed"
    • Convert output URL to base64 data URL
    • Return in GenerationOutput format

WHY: Replicate requires polling for async predictions. The generate() method encapsulates this complexity. TypeScript compiles, generate() method exists and doesn't throw immediately Replicate provider has working generate() method that calls prediction API

Task 2: Implement generate() method in fal.ai provider src/lib/providers/fal.ts 1. Implement the generate() method: - Accept GenerationInput with model, prompt, images, parameters - Call fal.ai's run endpoint: POST https://fal.run/{model.id} - Include prompt and parameters in request body - fal.ai is synchronous (waits for result)
  1. Handle auth:

    • Use "Key {apiKey}" header format (already established)
    • API key optional but rate limited without it
  2. Parse response:

    • Extract image/video URL from response
    • Convert to base64 data URL for consistency
    • Handle different output formats (images array, video URL, etc.)

WHY: fal.ai's synchronous API is simpler than Replicate. The generate() method normalizes the response format. TypeScript compiles, generate() method exists fal.ai provider has working generate() method that calls fal.run endpoint

Task 3: Update generate API route to dispatch by provider src/app/api/generate/route.ts 1. Update request type to accept either: - Legacy format: { model: ModelType, prompt, images, aspectRatio, resolution, useGoogleSearch } - New format: { selectedModel: SelectedModel, prompt, images, parameters }
  1. Add provider dispatch logic:

    if (body.selectedModel) {
      // New multi-provider path
      const { provider, modelId } = body.selectedModel;
      if (provider === "gemini") {
        // Use existing Gemini logic
      } else {
        // Get provider and call generate()
        const providerImpl = getProvider(provider);
        const model = await providerImpl.getModel(modelId);
        const result = await providerImpl.generate({
          model,
          prompt: body.prompt,
          images: body.images,
          parameters: body.parameters
        });
        return NextResponse.json(result);
      }
    } else {
      // Legacy Gemini path (existing code)
    }
    
  2. Extract Gemini-specific logic into helper function for clarity

  3. Ensure API key handling:

    • For Gemini: use GEMINI_API_KEY from env
    • For Replicate/fal: get from provider.getApiKey() (localStorage via client header)
  4. Add client headers for API keys:

    • Accept X-Replicate-API-Key and X-Fal-API-Key headers
    • Pass to provider implementations

WHY: The route becomes a dispatcher that preserves existing Gemini behavior while enabling new providers. npm run build succeeds, existing Gemini generation still works Generate route dispatches to correct provider, Gemini still works as before

Before declaring plan complete: - [ ] `npm run build` succeeds without errors - [ ] Existing Gemini generation works (test with existing workflow) - [ ] Replicate provider generate() method implemented - [ ] fal.ai provider generate() method implemented - [ ] API route accepts both legacy and new request formats

<success_criteria>

  • All tasks completed
  • All verification checks pass
  • Generate API routes to correct provider based on selectedModel
  • Gemini generation unchanged for backward compatibility
  • Replicate and fal.ai providers have generate() implementations </success_criteria>
After completion, create `.planning/phases/03-generate-node-refactor/03-02-SUMMARY.md`