diff --git a/.planning/phases/23-model-browser-improvements/23-01-PLAN.md b/.planning/phases/23-model-browser-improvements/23-01-PLAN.md new file mode 100644 index 00000000..2a92b199 --- /dev/null +++ b/.planning/phases/23-model-browser-improvements/23-01-PLAN.md @@ -0,0 +1,240 @@ +--- +phase: 23-model-browser-improvements +plan: 01 +type: execute +--- + + +Improve model browser UX with recently used models section, icon-based provider selector, and Gemini models in browse list. + +Purpose: Make it faster to access frequently used models and provide a consistent experience across all providers including Gemini. +Output: Enhanced ModelSearchDialog with recent models, icon-based provider filter, and Gemini models alongside Replicate/fal.ai models. + + + +~/.claude/get-shit-done/workflows/execute-phase.md +~/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md + +# Key source files +@src/components/modals/ModelSearchDialog.tsx +@src/components/FloatingActionBar.tsx +@src/store/workflowStore.ts +@src/app/api/models/route.ts +@src/types/index.ts +@src/lib/providers/types.ts + +# Related prior work +@.planning/phases/04-model-search-dialog/04-02-SUMMARY.md + +**Tech stack available:** +- React with Zustand for state +- ModelSearchDialog with existing filter patterns +- /api/models route with caching +- Provider icons already exist (Replicate, fal.ai SVGs in FloatingActionBar) + +**Established patterns:** +- Client-side search filtering +- Model cards with cover image, name, badges +- Provider badge colors (blue for Replicate, yellow for fal.ai) +- localStorage persistence for settings + +**Constraining decisions:** +- Phase 4: Client-side search filtering for Replicate +- Phase 4: Model card layout with badges and descriptions +- Gemini models use internal names (nano-banana, nano-banana-pro) + + + + + + Task 1: Add recently used models tracking and storage + src/store/workflowStore.ts, src/store/utils/localStorage.ts, src/types/index.ts + +Add recently used models tracking: + +1. In types/index.ts, add interface: +```typescript +export interface RecentModel { + provider: ProviderType; + modelId: string; + displayName: string; + timestamp: number; +} +``` + +2. In localStorage.ts, add: +- RECENT_MODELS_KEY constant: "node-banana-recent-models" +- getRecentModels(): RecentModel[] function (returns [] if not found) +- saveRecentModels(models: RecentModel[]): void function +- MAX_RECENT_MODELS = 8 (keep 8, show 4 in UI) + +3. In workflowStore.ts: +- Add state: recentModels: RecentModel[] (initialized from localStorage) +- Add action: trackModelUsage(model: { provider: ProviderType, modelId: string, displayName: string }) => void + - Remove existing entry for same modelId if present + - Prepend new entry with current timestamp + - Trim to MAX_RECENT_MODELS + - Save to localStorage + +Do NOT call trackModelUsage from the store itself - it will be called from ModelSearchDialog's handleSelectModel. + + +- Check workflowStore exports recentModels and trackModelUsage +- Check localStorage functions work (manually test in browser console) + + +- RecentModel type exists +- localStorage helpers for recent models exist +- Store has recentModels state and trackModelUsage action + + + + + Task 2: Add Gemini models to /api/models and update provider filter + src/app/api/models/route.ts + +Add Gemini image models to the models API response: + +1. Create GEMINI_IMAGE_MODELS constant at top of file: +```typescript +const GEMINI_IMAGE_MODELS: ProviderModel[] = [ + { + id: "nano-banana", + name: "Nano Banana", + description: "Fast image generation with Gemini 2.5 Flash. Supports text-to-image and image-to-image with aspect ratio control.", + provider: "gemini", + capabilities: ["text-to-image", "image-to-image"], + coverImage: null, + }, + { + id: "nano-banana-pro", + name: "Nano Banana Pro", + description: "High-quality image generation with Gemini 3 Pro. Supports text-to-image, image-to-image, resolution control (1K/2K/4K), and Google Search grounding.", + provider: "gemini", + capabilities: ["text-to-image", "image-to-image"], + coverImage: null, + }, +]; +``` + +2. In GET handler, update providersToFetch logic: +- If providerFilter === "gemini", only include Gemini models (don't fetch from external APIs) +- If providerFilter is null/all, include Gemini models in addition to external providers +- Gemini models are always available (no API key needed) + +3. Add Gemini models to allModels array at the start (before external provider fetch loop), so they appear first when no filter is applied. + +4. Add gemini to providerResults with { success: true, count: 2, cached: true } when Gemini models are included. + +Avoid: Fetching Gemini models from any external API - they are hardcoded. + + +- curl "http://localhost:3000/api/models" returns Gemini models in response +- curl "http://localhost:3000/api/models?provider=gemini" returns only Gemini models +- curl "http://localhost:3000/api/models?provider=fal" does NOT return Gemini models + + +- /api/models returns Gemini models (nano-banana, nano-banana-pro) +- Provider filter "gemini" works correctly +- Gemini models appear first in "all providers" results + + + + + Task 3: Update ModelSearchDialog with recent models and icon-based provider filter + src/components/modals/ModelSearchDialog.tsx + +Update ModelSearchDialog UI: + +1. Import and use recentModels and trackModelUsage from store: +```typescript +const { recentModels, trackModelUsage, ... } = useWorkflowStore(); +``` + +2. In handleSelectModel, call trackModelUsage before closing: +```typescript +trackModelUsage({ + provider: model.provider, + modelId: model.id, + displayName: model.name, +}); +``` + +3. Replace provider filter `