diff --git a/web-app/src/containers/ChatInput.tsx b/web-app/src/containers/ChatInput.tsx index 8f788446d..8b2c0b05e 100644 --- a/web-app/src/containers/ChatInput.tsx +++ b/web-app/src/containers/ChatInput.tsx @@ -14,7 +14,7 @@ import { } from '@/components/ui/tooltip' import { ArrowRight } from 'lucide-react' import { - IconPaperclip, + IconPhoto, IconWorld, IconAtom, IconEye, @@ -56,7 +56,7 @@ const ChatInput = ({ model, className, initialMessage }: ChatInputProps) => { const maxRows = 10 - const { selectedModel } = useModelProvider() + const { selectedModel, selectedProvider } = useModelProvider() const { sendMessage } = useChat() const [message, setMessage] = useState('') const [dropdownToolsAvailable, setDropdownToolsAvailable] = useState(false) @@ -100,7 +100,7 @@ const ChatInput = ({ model, className, initialMessage }: ChatInputProps) => { if (selectedModel?.id) { try { // Only check mmproj for llamacpp provider - if (model?.provider === 'llamacpp') { + if (selectedProvider === 'llamacpp') { const hasLocalMmproj = await checkMmprojExists(selectedModel.id) setHasMmproj(hasLocalMmproj) } else { @@ -115,7 +115,7 @@ const ChatInput = ({ model, className, initialMessage }: ChatInputProps) => { } checkMmprojSupport() - }, [selectedModel?.id, selectedModel?.capabilities, model?.provider]) + }, [selectedModel?.id, selectedProvider]) // Check if there are active MCP servers const hasActiveMCPServers = connectedServers.length > 0 || tools.length > 0 @@ -534,7 +534,7 @@ const ChatInput = ({ model, className, initialMessage }: ChatInputProps) => { className="h-6 p-1 ml-1 flex items-center justify-center rounded-sm hover:bg-main-view-fg/10 transition-all duration-200 ease-in-out gap-1" onClick={handleAttachmentClick} > - + ({ vi.mock('@/services/models', () => ({ stopAllModels: vi.fn(), + checkMmprojExists: vi.fn(() => Promise.resolve(true)), })) vi.mock('../MovingBorder', () => ({ @@ -347,9 +348,12 @@ describe('ChatInput', () => { const user = userEvent.setup() renderWithRouter() - // File upload is rendered as hidden input element - const fileInput = document.querySelector('input[type="file"]') - expect(fileInput).toBeInTheDocument() + // Wait for async effects to complete (mmproj check) + await waitFor(() => { + // File upload is rendered as hidden input element + const fileInput = document.querySelector('input[type="file"]') + expect(fileInput).toBeInTheDocument() + }) }) it('disables input when streaming', () => { @@ -382,4 +386,28 @@ describe('ChatInput', () => { expect(toolsIcon).toBeInTheDocument() }) }) + + it('uses selectedProvider for provider checks', () => { + // Test that the component correctly uses selectedProvider instead of selectedModel.provider + vi.mocked(useModelProvider).mockReturnValue({ + selectedModel: { + id: 'test-model', + capabilities: ['vision'], + }, + providers: [], + getModelBy: vi.fn(), + selectModelProvider: vi.fn(), + selectedProvider: 'llamacpp', + setProviders: vi.fn(), + getProviderByName: vi.fn(), + updateProvider: vi.fn(), + addProvider: vi.fn(), + deleteProvider: vi.fn(), + deleteModel: vi.fn(), + deletedModels: [], + }) + + // This test ensures the component renders without errors when using selectedProvider + expect(() => renderWithRouter()).not.toThrow() + }) }) \ No newline at end of file