8.3 KiB
| phase | plan | type |
|---|---|---|
| 23-model-browser-improvements | 1 | execute |
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.
<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.mdKey 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)
- In types/index.ts, add interface:
export interface RecentModel {
provider: ProviderType;
modelId: string;
displayName: string;
timestamp: number;
}
- 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)
- 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
- Create GEMINI_IMAGE_MODELS constant at top of file:
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,
},
];
- 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)
-
Add Gemini models to allModels array at the start (before external provider fetch loop), so they appear first when no filter is applied.
-
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
- Import and use recentModels and trackModelUsage from store:
const { recentModels, trackModelUsage, ... } = useWorkflowStore();
- In handleSelectModel, call trackModelUsage before closing:
trackModelUsage({
provider: model.provider,
modelId: model.id,
displayName: model.name,
});
- Replace provider filter
<select>with icon-based button group:
- "All" option (no icon, just text "All")
- Gemini icon (use a sparkle/star icon from existing SVG patterns, add green-500 badge color)
- Replicate icon (existing SVG from FloatingActionBar)
- fal.ai icon (existing SVG from FloatingActionBar)
- Style: horizontal button group with hover states, active state shows filled background
- Use existing badge colors: green for Gemini, blue for Replicate, yellow for fal.ai
- Add getProviderBadgeColor case for "gemini":
case "gemini":
return "bg-green-500/20 text-green-300";
- Add "Recently Used" section at top of model list (after filter bar, before loading state):
- Only show if recentModels.length > 0
- Show max 4 models (slice(0, 4))
- Use same model card UI as main list
- Add subtle "Recent" label/header
- Filter recent models by current capability filter (image/video/all)
- Add divider between recent section and main list
- Update provider badge display text:
- "gemini" -> "Gemini"
- Keep existing: "replicate" -> "Replicate", "fal" -> "fal.ai"
Styling notes:
- Icon buttons: p-2, rounded, hover:bg-neutral-700, active state bg-neutral-600
- Recent section: slightly different background (bg-neutral-700/30), smaller gap, "Recently Used" label text-xs text-neutral-500
- Gemini icon: Use a simple sparkle/AI icon (4-pointed star or similar)
- Open ModelSearchDialog from fal.ai icon
- Verify Gemini, Replicate, fal.ai icons appear in provider filter
- Select a model, reopen dialog - model appears in "Recently Used"
- Filter by provider - recent models also filter
- Filter by capability - recent models also filter
- Provider filter uses icons instead of dropdown
- Gemini option available in provider filter
- Recently used section shows at top of model list
- Recent models persist across dialog opens
- Model selection tracks usage
<success_criteria>
- All tasks completed
- All verification checks pass
- No TypeScript errors
- Gemini models browsable alongside Replicate/fal.ai
- Recently used models section functional
- Icon-based provider filter implemented </success_criteria>