6.1 KiB
| phase | plan | type |
|---|---|---|
| 01-provider-infrastructure | 2 | execute |
Purpose: Establish the interface contract that all providers (Gemini, Replicate, fal.ai) will implement, enabling uniform access to different AI services. Output: Provider abstraction interfaces and types in src/lib/providers/ ready for implementation in Phase 2.
<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.mdPrior plan context: Plan 01-01 added ProviderType, ProviderConfig, and ProviderSettings types.
Key files: @src/types/index.ts @src/app/api/generate/route.ts
Established patterns:
- Feature libraries in
src/lib/{feature}/(see quickstart/) - Types defined with PascalCase interfaces
- Prefer fetch over SDKs per PROJECT.md constraints
Constraints:
- No hardcoded schemas - model parameters fetched at runtime
- Fetch over SDKs for bundle size
- Dynamic model discovery for future-proofing
-
ProviderModelinterface - represents a model from any provider:interface ProviderModel { id: string; // Provider-specific model ID (e.g., "stability-ai/sdxl") name: string; // Display name description: string | null; // Model description provider: ProviderType; // Which provider this is from capabilities: ModelCapability[]; // What it can do coverImage?: string; // Thumbnail URL pricing?: { // Optional pricing info type: "per-run" | "per-second"; amount: number; currency: string; }; } -
ModelCapabilityunion:type ModelCapability = "text-to-image" | "image-to-image" | "text-to-video" | "image-to-video"; -
GenerationInputinterface - unified input for all providers:interface GenerationInput { model: ProviderModel; prompt: string; images?: string[]; // Base64 data URLs or HTTP URLs parameters?: Record<string, unknown>; // Model-specific params } -
GenerationOutputinterface:interface GenerationOutput { success: boolean; outputs?: Array<{ type: "image" | "video"; data: string; // Base64 data URL url?: string; // Original URL if applicable }>; error?: string; } -
ProviderInterface- contract all providers implement:interface ProviderInterface { id: ProviderType; name: string; // Model discovery listModels(): Promise<ProviderModel[]>; getModel(modelId: string): Promise<ProviderModel | null>; searchModels(query: string): Promise<ProviderModel[]>; // Generation generate(input: GenerationInput): Promise<GenerationOutput>; // Utilities isConfigured(): boolean; // Check if API key is set getApiKey(): string | null; }
Import ProviderType from "@/types". Export all interfaces and types. npm run build passes, types can be imported from "@/lib/providers/types" Provider abstraction interfaces defined in src/lib/providers/types.ts
Task 2: Create provider registry and factory src/lib/providers/index.ts Create provider registry that will be populated by specific provider implementations in Phase 2:-
Create
src/lib/providers/index.tswith: -
Export all types from types.ts:
export * from "./types"; -
Provider registry (empty for now, filled in Phase 2):
import { ProviderType } from "@/types"; import { ProviderInterface } from "./types"; // Registry populated by provider implementations const providerRegistry: Partial<Record<ProviderType, ProviderInterface>> = {}; export function registerProvider(provider: ProviderInterface): void { providerRegistry[provider.id] = provider; } export function getProvider(id: ProviderType): ProviderInterface | undefined { return providerRegistry[id]; } export function getConfiguredProviders(): ProviderInterface[] { return Object.values(providerRegistry).filter( (p): p is ProviderInterface => p !== undefined && p.isConfigured() ); } export function getAllProviders(): ProviderInterface[] { return Object.values(providerRegistry).filter( (p): p is ProviderInterface => p !== undefined ); } -
Add JSDoc comments explaining:
- Registry will be populated when provider modules are imported
- Phase 2 will add Replicate and fal.ai implementations
- Gemini implementation is special-cased in existing generate route for now
This creates the foundation without implementing actual providers yet. npm run build passes, registry functions can be imported from "@/lib/providers" Provider registry and factory functions exist in src/lib/providers/index.ts
Before declaring plan complete: - [ ] `npm run build` succeeds without errors - [ ] `npm run lint` passes - [ ] src/lib/providers/types.ts exists with all interfaces - [ ] src/lib/providers/index.ts exports types and registry functions - [ ] Types can be imported: `import { ProviderModel, ProviderInterface } from "@/lib/providers"`<success_criteria>
- All tasks completed
- All verification checks pass
- No TypeScript errors
- Provider abstraction layer ready for Phase 2 implementations
- Phase 1 complete </success_criteria>
Include in summary:
- Phase 1 complete, ready for Phase 2: Model Discovery