|
|
@@ -1,5 +1,12 @@
|
|
|
-import { VSCodeDropdown, VSCodeLink, VSCodeOption, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
|
|
|
-import React, { useMemo } from "react"
|
|
|
+import {
|
|
|
+ VSCodeDropdown,
|
|
|
+ VSCodeLink,
|
|
|
+ VSCodeOption,
|
|
|
+ VSCodeRadio,
|
|
|
+ VSCodeRadioGroup,
|
|
|
+ VSCodeTextField,
|
|
|
+} from "@vscode/webview-ui-toolkit/react"
|
|
|
+import React, { useCallback, useEffect, useMemo, useState } from "react"
|
|
|
import {
|
|
|
ApiConfiguration,
|
|
|
ModelInfo,
|
|
|
@@ -15,6 +22,9 @@ import {
|
|
|
} from "../../../src/shared/api"
|
|
|
import { useExtensionState } from "../context/ExtensionStateContext"
|
|
|
import VSCodeButtonLink from "./VSCodeButtonLink"
|
|
|
+import { ExtensionMessage } from "../../../src/shared/ExtensionMessage"
|
|
|
+import { useEvent, useInterval } from "react-use"
|
|
|
+import { vscode } from "../utils/vscode"
|
|
|
|
|
|
interface ApiOptionsProps {
|
|
|
showModelOptions: boolean
|
|
|
@@ -23,6 +33,8 @@ interface ApiOptionsProps {
|
|
|
|
|
|
const ApiOptions: React.FC<ApiOptionsProps> = ({ showModelOptions, apiErrorMessage }) => {
|
|
|
const { apiConfiguration, setApiConfiguration, uriScheme } = useExtensionState()
|
|
|
+ const [ollamaModels, setOllamaModels] = useState<string[]>([])
|
|
|
+
|
|
|
const handleInputChange = (field: keyof ApiConfiguration) => (event: any) => {
|
|
|
setApiConfiguration({ ...apiConfiguration, [field]: event.target.value })
|
|
|
}
|
|
|
@@ -31,6 +43,27 @@ const ApiOptions: React.FC<ApiOptionsProps> = ({ showModelOptions, apiErrorMessa
|
|
|
return normalizeApiConfiguration(apiConfiguration)
|
|
|
}, [apiConfiguration])
|
|
|
|
|
|
+ // Poll ollama models
|
|
|
+ const requestOllamaModels = useCallback(() => {
|
|
|
+ if (selectedProvider === "ollama") {
|
|
|
+ vscode.postMessage({ type: "requestOllamaModels", text: apiConfiguration?.ollamaBaseUrl })
|
|
|
+ }
|
|
|
+ }, [selectedProvider, apiConfiguration?.ollamaBaseUrl])
|
|
|
+ useEffect(() => {
|
|
|
+ if (selectedProvider === "ollama") {
|
|
|
+ requestOllamaModels()
|
|
|
+ }
|
|
|
+ }, [selectedProvider, requestOllamaModels])
|
|
|
+ useInterval(requestOllamaModels, selectedProvider === "ollama" ? 2000 : null)
|
|
|
+
|
|
|
+ const handleMessage = useCallback((event: MessageEvent) => {
|
|
|
+ const message: ExtensionMessage = event.data
|
|
|
+ if (message.type === "ollamaModels" && message.models) {
|
|
|
+ setOllamaModels(message.models)
|
|
|
+ }
|
|
|
+ }, [])
|
|
|
+ useEvent("message", handleMessage)
|
|
|
+
|
|
|
/*
|
|
|
VSCodeDropdown has an open bug where dynamically rendered options don't auto select the provided value prop. You can see this for yourself by comparing it with normal select/option elements, which work as expected.
|
|
|
https://github.com/microsoft/vscode-webview-ui-toolkit/issues/433
|
|
|
@@ -295,8 +328,8 @@ const ApiOptions: React.FC<ApiOptionsProps> = ({ showModelOptions, apiErrorMessa
|
|
|
}}>
|
|
|
You can use any OpenAI compatible API with models that support tool use.{" "}
|
|
|
<span style={{ color: "var(--vscode-errorForeground)" }}>
|
|
|
- (<span style={{ fontWeight: 500 }}>Note:</span> Claude Dev uses complex prompts, so less
|
|
|
- capable models may not work as expected.)
|
|
|
+ (<span style={{ fontWeight: 500 }}>Note:</span> Claude Dev uses complex prompts and works
|
|
|
+ best with Claude models. Less capable models may not work as expected.)
|
|
|
</span>
|
|
|
</p>
|
|
|
</div>
|
|
|
@@ -304,6 +337,14 @@ const ApiOptions: React.FC<ApiOptionsProps> = ({ showModelOptions, apiErrorMessa
|
|
|
|
|
|
{selectedProvider === "ollama" && (
|
|
|
<div>
|
|
|
+ <VSCodeTextField
|
|
|
+ value={apiConfiguration?.ollamaBaseUrl || ""}
|
|
|
+ style={{ width: "100%" }}
|
|
|
+ type="url"
|
|
|
+ onInput={handleInputChange("ollamaBaseUrl")}
|
|
|
+ placeholder={"Default: http://localhost:11434"}>
|
|
|
+ <span style={{ fontWeight: 500 }}>Base URL (optional)</span>
|
|
|
+ </VSCodeTextField>
|
|
|
<VSCodeTextField
|
|
|
value={apiConfiguration?.ollamaModelId || ""}
|
|
|
style={{ width: "100%" }}
|
|
|
@@ -311,26 +352,52 @@ const ApiOptions: React.FC<ApiOptionsProps> = ({ showModelOptions, apiErrorMessa
|
|
|
placeholder={"e.g. llama3.1"}>
|
|
|
<span style={{ fontWeight: 500 }}>Model ID</span>
|
|
|
</VSCodeTextField>
|
|
|
+ {ollamaModels.length > 0 && (
|
|
|
+ <VSCodeRadioGroup
|
|
|
+ value={
|
|
|
+ ollamaModels.includes(apiConfiguration?.ollamaModelId || "")
|
|
|
+ ? apiConfiguration?.ollamaModelId
|
|
|
+ : ""
|
|
|
+ }
|
|
|
+ onChange={(e) => {
|
|
|
+ const value = (e.target as HTMLInputElement)?.value
|
|
|
+ // need to check value first since radio group returns empty string sometimes
|
|
|
+ if (value) {
|
|
|
+ handleInputChange("ollamaModelId")({
|
|
|
+ target: { value },
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }}>
|
|
|
+ {ollamaModels.map((model) => (
|
|
|
+ <VSCodeRadio
|
|
|
+ key={model}
|
|
|
+ value={model}
|
|
|
+ checked={apiConfiguration?.ollamaModelId === model}>
|
|
|
+ {model}
|
|
|
+ </VSCodeRadio>
|
|
|
+ ))}
|
|
|
+ </VSCodeRadioGroup>
|
|
|
+ )}
|
|
|
<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
|
|
|
- with Ollama, see their
|
|
|
+ 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" }}>
|
|
|
quickstart guide.
|
|
|
</VSCodeLink>{" "}
|
|
|
- You can use any models that support{" "}
|
|
|
+ You can use any model that supports{" "}
|
|
|
<VSCodeLink href="https://ollama.com/search?c=tools" style={{ display: "inline" }}>
|
|
|
tool use.
|
|
|
</VSCodeLink>
|
|
|
<span style={{ color: "var(--vscode-errorForeground)" }}>
|
|
|
- (<span style={{ fontWeight: 500 }}>Note:</span> Claude Dev uses complex prompts, so less
|
|
|
- capable models may not work as expected.)
|
|
|
+ (<span style={{ fontWeight: 500 }}>Note:</span> Claude Dev uses complex prompts and works
|
|
|
+ best with Claude models. Less capable models may not work as expected.)
|
|
|
</span>
|
|
|
</p>
|
|
|
</div>
|