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.
 
 

8.3 KiB

phase plan type
23-model-browser-improvements 1 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.

<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

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:
export interface RecentModel {
  provider: ProviderType;
  modelId: string;
  displayName: string;
  timestamp: number;
}
  1. 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)
  1. 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:
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,
  },
];
  1. 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)
  1. Add Gemini models to allModels array at the start (before external provider fetch loop), so they appear first when no filter is applied.

  2. 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.

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:
const { recentModels, trackModelUsage, ... } = useWorkflowStore();
  1. In handleSelectModel, call trackModelUsage before closing:
trackModelUsage({
  provider: model.provider,
  modelId: model.id,
  displayName: model.name,
});
  1. 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
  1. Add getProviderBadgeColor case for "gemini":
case "gemini":
  return "bg-green-500/20 text-green-300";
  1. 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
  1. 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
Before declaring phase complete: - [ ] npm run build succeeds without errors - [ ] ModelSearchDialog shows Gemini models when "All" or "Gemini" filter selected - [ ] Recently used models appear at top after selecting any model - [ ] Provider filter uses icons (Gemini, Replicate, fal.ai, All) - [ ] Recent models persist after page refresh - [ ] Capability filter (image/video) works for both recent and main lists

<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>
After completion, create `.planning/phases/23-model-browser-improvements/23-01-SUMMARY.md`