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