// // SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // "use client" import { useState, useEffect } from "react" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Alert, AlertDescription } from "@/components/ui/alert" import { Loader2, Server, CheckCircle, XCircle, RefreshCw } from "lucide-react" import { OllamaIcon } from "@/components/ui/ollama-icon" interface OllamaConnectionProps { onConnectionChange?: (connected: boolean, models?: string[]) => void } export function OllamaConnection({ onConnectionChange }: OllamaConnectionProps) { const [baseUrl, setBaseUrl] = useState('http://localhost:11434') const [isConnecting, setIsConnecting] = useState(false) const [isConnected, setIsConnected] = useState(false) const [availableModels, setAvailableModels] = useState([]) const [selectedModel, setSelectedModel] = useState('llama3.2') const [error, setError] = useState(null) const [lastChecked, setLastChecked] = useState(null) // Load settings from localStorage useEffect(() => { const savedUrl = localStorage.getItem('ollama_base_url') const savedModel = localStorage.getItem('ollama_model') if (savedUrl) setBaseUrl(savedUrl) if (savedModel) setSelectedModel(savedModel) // Auto-test connection on load testConnection() }, []) // Save settings to localStorage useEffect(() => { localStorage.setItem('ollama_base_url', baseUrl) localStorage.setItem('ollama_model', selectedModel) }, [baseUrl, selectedModel]) const testConnection = async () => { setIsConnecting(true) setError(null) try { const response = await fetch('/api/ollama?action=test-connection') const result = await response.json() if (result.connected) { setIsConnected(true) setAvailableModels(result.models || []) setLastChecked(new Date()) onConnectionChange?.(true, result.models) } else { setIsConnected(false) setError(result.error || 'Connection failed') onConnectionChange?.(false) } } catch (err) { setIsConnected(false) setError(err instanceof Error ? err.message : 'Connection test failed') onConnectionChange?.(false) } finally { setIsConnecting(false) } } const formatUrl = (url: string) => { // Ensure the URL ends with the correct path for Ollama API let formatted = url.trim() if (!formatted.startsWith('http://') && !formatted.startsWith('https://')) { formatted = 'http://' + formatted } return formatted } return ( Ollama Connection Connect to your local Ollama server for offline LLM processing
setBaseUrl(e.target.value)} placeholder="http://localhost:11434" className="flex-1" />
{/* Connection Status */}
{isConnected ? ( Connected ) : ( Disconnected )} {lastChecked && ( Last checked: {lastChecked.toLocaleTimeString()} )}
{/* Error Display */} {error && ( {error} )} {/* Available Models */} {isConnected && availableModels.length > 0 && (
{availableModels.map((model) => ( setSelectedModel(model)} > {model} ))}
Selected model: {selectedModel}
)} {/* Instructions */} {!isConnected && ( Make sure Ollama is installed and running. Visit{" "} ollama.com {" "} for installation instructions. )}
) }