--- phase: 06-chat-ui-redesign plan: 01 status: complete completed_at: "2026-04-02T12:00:00Z" --- # Plan 06-01 Summary: Backend + ModelSelectorPill ## Completed Tasks ### Task 1: Fix Rust model scan to top-level only ✅ - **Status**: Already implemented - `scan_model_dir_top_level()` function exists in `model_files.rs` - `scan_models` Tauri command uses top-level scan (not recursive) - All 5 tests pass including `scan_model_dir_returns_only_top_level_gguf` ### Task 2: Create ModelSelectorPill + wire into ChatView + clean Sidebar ✅ - **ModelSelectorPill.tsx**: Created at `tauri-app/src/components/ModelSelectorPill.tsx` - Extracts model deduplication logic from Sidebar - Renders compact pill button with status dot and dropdown - Shows spinner when `isSwapping` is true - Uses `getDisplayName` and `isInChatSelector` from modelAlias - **Sidebar.tsx**: Cleaned - Removed `model-section` block (lines 131-170) - Removed model-related props: `models`, `localModels`, `selectedModel`, `onModelChange`, `onModelSwap`, `isSwapping`, `status` - Removed `ModelInfo` and `RuntimeModelFile` imports - **ChatView.tsx**: Updated - Added model props to Props interface (lines 26-32) - Imported `ModelSelectorPill` component - Rendered `` in hero input (line 627) - Rendered `` in regular input (line 851) - **App.tsx**: Updated - Removed model props from `` component - Added model props to ``: `models`, `localModels`, `selectedModel`, `onModelChange`, `onModelSwap`, `isSwapping`, `status` - **ChatView.test.tsx**: Fixed - Added `defaultChatViewProps` with required model props - Spread `{...defaultChatViewProps}` to all test renders ## Verification Results ### TypeScript Build ✅ ``` > tsc && vite build ✓ 6325 modules transformed. ✓ built in 5.50s ``` ### Rust Tests ✅ ``` running 5 tests test model_files::tests::scan_model_dir_filters_and_sorts_gguf_files ... ok test model_files::tests::scan_model_dir_ignores_directories_named_like_models ... ok test model_files::tests::scan_model_dir_skips_hidden_directories ... ok test model_files::tests::scan_model_dir_recursive_finds_nested_gguf ... ok test model_files::tests::scan_model_dir_returns_only_top_level_gguf ... ok test result: ok. 5 passed; 0 failed ``` ## Files Modified - `tauri-app/src-tauri/src/model_files.rs` (already had top-level scan) - `tauri-app/src/components/ModelSelectorPill.tsx` (created) - `tauri-app/src/components/Sidebar.tsx` (cleaned) - `tauri-app/src/components/ChatView.tsx` (added model props + ModelSelectorPill) - `tauri-app/src/App.tsx` (routed model props to ChatView) - `tauri-app/src/components/ChatView.test.tsx` (fixed tests) ## Success Criteria Met - [x] Top-level model scan: `scan_models("./models")` returns only `.gguf` files directly in the folder - [x] Model selector visible in chat input pill (hero screen and regular screen) - [x] No model selector in the sidebar - [x] TypeScript and Rust compile without errors