Browse Source

docs(23): create phase plan

Phase 23: Model Browser Improvements
- 1 plan created
- 3 tasks defined
- Ready for execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
handoff-20260429-1057
shrimbly 6 months ago
parent
commit
170a240407
  1. 240
      .planning/phases/23-model-browser-improvements/23-01-PLAN.md

240
.planning/phases/23-model-browser-improvements/23-01-PLAN.md

@ -0,0 +1,240 @@
---
phase: 23-model-browser-improvements
plan: 01
type: execute
---
<objective>
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.
</objective>
<execution_context>
~/.claude/get-shit-done/workflows/execute-phase.md
~/.claude/get-shit-done/templates/summary.md
</execution_context>
<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)
</context>
<tasks>
<task type="auto">
<name>Task 1: Add recently used models tracking and storage</name>
<files>src/store/workflowStore.ts, src/store/utils/localStorage.ts, src/types/index.ts</files>
<action>
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.
</action>
<verify>
- Check workflowStore exports recentModels and trackModelUsage
- Check localStorage functions work (manually test in browser console)
</verify>
<done>
- RecentModel type exists
- localStorage helpers for recent models exist
- Store has recentModels state and trackModelUsage action
</done>
</task>
<task type="auto">
<name>Task 2: Add Gemini models to /api/models and update provider filter</name>
<files>src/app/api/models/route.ts</files>
<action>
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.
</action>
<verify>
- 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
</verify>
<done>
- /api/models returns Gemini models (nano-banana, nano-banana-pro)
- Provider filter "gemini" works correctly
- Gemini models appear first in "all providers" results
</done>
</task>
<task type="auto">
<name>Task 3: Update ModelSearchDialog with recent models and icon-based provider filter</name>
<files>src/components/modals/ModelSearchDialog.tsx</files>
<action>
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 `<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
4. Add getProviderBadgeColor case for "gemini":
```typescript
case "gemini":
return "bg-green-500/20 text-green-300";
```
5. 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
6. 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)
</action>
<verify>
- 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
</verify>
<done>
- 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
</done>
</task>
</tasks>
<verification>
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
</verification>
<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>
<output>
After completion, create `.planning/phases/23-model-browser-improvements/23-01-SUMMARY.md`
</output>
Loading…
Cancel
Save