Implement generation via fal.ai's fal.run API:
- POST to https://fal.run/{modelId} with prompt and parameters
- Use "Key {apiKey}" auth header (works without key but rate limited)
- Extract image URL from response (handles images array, image object, or output string)
- Fetch image and convert to base64 data URL
- Return GenerationOutput with type: "image"
Note: Image inputs skipped for now (Phase 5 adds URL server)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement generation via Replicate's prediction API:
- POST to /predictions with model version and prompt
- Poll /predictions/{id} until succeeded/failed/canceled
- Fetch output image URL and convert to base64 data URL
- Return GenerationOutput with type: "image"
Note: Image inputs skipped for now (Phase 5 adds URL server)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Export cache utilities from provider index and add listAllModels/
searchAllModels helper functions for multi-provider operations.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add in-memory cache for provider model lists with 10-minute TTL.
Includes get/set/invalidate functions and cache key generation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add defensive null checks before calling .map() on data.results
in both the API route and provider implementation. Returns empty
array with success:true when results is undefined, preventing
"Cannot read properties of undefined (reading 'map')" crash.
Fixes: UAT-001 from 02-01-ISSUES.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
fal.ai API only accepts a single category parameter, but we were
sending multiple categories. Now we fetch all active models and
filter client-side using the existing isRelevantModel() function.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement ProviderInterface for fal.ai model marketplace:
- Model discovery via REST API (listModels, searchModels, getModel)
- Filter to relevant categories (text-to-image, image-to-image, text-to-video, image-to-video)
- Optional API key auth (works without key but with rate limits)
- Self-registration in provider registry on import
- Stub generate() for Phase 3 implementation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Implement ProviderInterface for Replicate.com
- listModels() fetches from /v1/models endpoint
- searchModels() uses /v1/search endpoint
- getModel() retrieves single model by owner/name
- inferCapabilities() from model name/description
- Self-registers via registerProvider() on import
- API key read from localStorage provider settings
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add provider registry in src/lib/providers/index.ts:
- Export all types from types.ts
- providerRegistry for storing provider implementations
- registerProvider() for providers to self-register
- getProvider() to retrieve provider by type
- getConfiguredProviders() to get providers with API keys
- getAllProviders() to get all registered providers
Registry will be populated when provider modules are imported
in Phase 2 (Replicate and fal.ai implementations).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add provider abstraction layer in src/lib/providers/types.ts:
- ProviderModel interface for normalized model metadata
- ModelCapability union type for model capabilities
- GenerationInput/GenerationOutput interfaces for unified I/O
- ProviderInterface contract for provider implementations
This establishes the interface contract that all providers
(Gemini, Replicate, fal.ai) will implement in Phase 2.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>