Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import { StringRequest } from "@shared/proto/cline/common"
import { Mode } from "@shared/storage/types"
import { VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import { useCallback, useEffect, useState } from "react"
import { useInterval } from "react-use"
import UseCustomPromptCheckbox from "@/components/settings/UseCustomPromptCheckbox"
import { useExtensionState } from "@/context/ExtensionStateContext"
import { ModelsServiceClient } from "@/services/grpc-client"
import { ApiKeyField } from "../common/ApiKeyField"
import { BaseUrlField } from "../common/BaseUrlField"
import { DebouncedTextField } from "../common/DebouncedTextField"
import OllamaModelPicker from "../OllamaModelPicker"
import { getModeSpecificFields } from "../utils/providerUtils"
import { useApiConfigurationHandlers } from "../utils/useApiConfigurationHandlers"
/**
* Props for the OllamaProvider component
*/
interface OllamaProviderProps {
showModelOptions: boolean
isPopup?: boolean
currentMode: Mode
}
/**
* The Ollama provider configuration component
*/
export const OllamaProvider = ({ showModelOptions, isPopup, currentMode }: OllamaProviderProps) => {
const { apiConfiguration } = useExtensionState()
const { handleFieldChange, handleModeFieldChange } = useApiConfigurationHandlers()
const { ollamaModelId } = getModeSpecificFields(apiConfiguration, currentMode)
const [ollamaModels, setOllamaModels] = useState<string[]>([])
// Poll ollama models
const requestOllamaModels = useCallback(async () => {
try {
const response = await ModelsServiceClient.getOllamaModels(
StringRequest.create({
value: apiConfiguration?.ollamaBaseUrl || "",
}),
)
if (response && response.values) {
setOllamaModels(response.values)
}
} catch (error) {
console.error("Failed to fetch Ollama models:", error)
setOllamaModels([])
}
}, [apiConfiguration?.ollamaBaseUrl])
useEffect(() => {
requestOllamaModels()
}, [requestOllamaModels])
useInterval(requestOllamaModels, 2000)
return (
<div className="flex flex-col gap-2">
<BaseUrlField
initialValue={apiConfiguration?.ollamaBaseUrl}
label="Use custom base URL"
onChange={(value) => handleFieldChange("ollamaBaseUrl", value)}
placeholder="Default: http://localhost:11434"
/>
{apiConfiguration?.ollamaBaseUrl && (
<ApiKeyField
helpText="Optional API key for authenticated Ollama instances or cloud services. Leave empty for local installations."
initialValue={apiConfiguration?.ollamaApiKey || ""}
onChange={(value) => handleFieldChange("ollamaApiKey", value)}
placeholder="Enter API Key (optional)..."
providerName="Ollama"
/>
)}
{/* Model selection - use filterable picker */}
<label htmlFor="ollama-model-selection">
<span className="font-semibold">Model</span>
</label>
<OllamaModelPicker
ollamaModels={ollamaModels}
onModelChange={(modelId) => {
handleModeFieldChange({ plan: "planModeOllamaModelId", act: "actModeOllamaModelId" }, modelId, currentMode)
}}
placeholder={ollamaModels.length > 0 ? "Search and select a model..." : "e.g. llama3.1"}
selectedModelId={ollamaModelId || ""}
/>
{/* Show status message based on model availability */}
{ollamaModels.length === 0 && (
<p className="text-sm mt-1 text-description italic">
Unable to fetch models from Ollama server. Please ensure Ollama is running and accessible, or enter the model
ID manually above.
</p>
)}
<DebouncedTextField
initialValue={apiConfiguration?.ollamaApiOptionsCtxNum || "32768"}
onChange={(v) => handleFieldChange("ollamaApiOptionsCtxNum", v || undefined)}
placeholder={"e.g. 32768"}
style={{ width: "100%" }}>
<span className="font-semibold">Model Context Window</span>
</DebouncedTextField>
{showModelOptions && (
<>
<DebouncedTextField
initialValue={apiConfiguration?.requestTimeoutMs ? apiConfiguration.requestTimeoutMs.toString() : "30000"}
onChange={(value) => {
// Convert to number, with validation
const numValue = parseInt(value, 10)
if (!Number.isNaN(numValue) && numValue > 0) {
handleFieldChange("requestTimeoutMs", numValue)
}
}}
placeholder="Default: 30000 (30 seconds)"
style={{ width: "100%" }}>
<span className="font-semibold">Request Timeout (ms)</span>
</DebouncedTextField>
<p className="text-xs mt-0 text-description">
Maximum time in milliseconds to wait for API responses before timing out.
</p>
</>
)}
<UseCustomPromptCheckbox providerId="ollama" />
<p
style={{
fontSize: "12px",
marginTop: "5px",
color: "var(--vscode-descriptionForeground)",
}}>
Ollama allows you to run models locally on your computer. For instructions on how to get started, see their{" "}
<VSCodeLink
href="https://github.com/ollama/ollama/blob/main/README.md"
style={{ display: "inline", fontSize: "inherit" }}>
quickstart guide.
</VSCodeLink>{" "}
<span style={{ color: "var(--vscode-errorForeground)" }}>
(<span style={{ fontWeight: 500 }}>Note:</span> AI-Hydro uses complex prompts and works best with Claude
models. Less capable models may not work as expected.)
</span>
</p>
</div>
)
}
|