Skip to content

Commit 2b8cdb7

Browse files
committed
feat: add Ollama API key support for Turbo mode
- Add ollamaApiKey field to ProviderSettings schema - Add ollamaApiKey to SECRET_STATE_KEYS for secure storage - Update Ollama and NativeOllama providers to use API key for authentication - Add UI field for Ollama API key (shown when custom base URL is provided) - Add test coverage for API key functionality This enables users to use Ollama Turbo with datacenter-grade hardware by providing an API key for authenticated Ollama instances or cloud services.
1 parent a79c3d0 commit 2b8cdb7

File tree

6 files changed

+45
-3
lines changed

6 files changed

+45
-3
lines changed

packages/types/src/global-settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ export const SECRET_STATE_KEYS = [
174174
"awsSecretKey",
175175
"awsSessionToken",
176176
"openAiApiKey",
177+
"ollamaApiKey",
177178
"geminiApiKey",
178179
"openAiNativeApiKey",
179180
"cerebrasApiKey",

packages/types/src/provider-settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ const openAiSchema = baseProviderSettingsSchema.extend({
186186
const ollamaSchema = baseProviderSettingsSchema.extend({
187187
ollamaModelId: z.string().optional(),
188188
ollamaBaseUrl: z.string().optional(),
189+
ollamaApiKey: z.string().optional(),
189190
})
190191

191192
const vsCodeLmSchema = baseProviderSettingsSchema.extend({

src/api/providers/__tests__/ollama.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,17 @@ describe("OllamaHandler", () => {
9292
})
9393
expect(handlerWithoutUrl).toBeInstanceOf(OllamaHandler)
9494
})
95+
96+
it("should use API key when provided", () => {
97+
const handlerWithApiKey = new OllamaHandler({
98+
apiModelId: "llama2",
99+
ollamaModelId: "llama2",
100+
ollamaBaseUrl: "https://ollama.com",
101+
ollamaApiKey: "test-api-key",
102+
})
103+
expect(handlerWithApiKey).toBeInstanceOf(OllamaHandler)
104+
// The API key will be used in the Authorization header
105+
})
95106
})
96107

97108
describe("createMessage", () => {

src/api/providers/native-ollama.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,19 @@ export class NativeOllamaHandler extends BaseProvider implements SingleCompletio
140140
private ensureClient(): Ollama {
141141
if (!this.client) {
142142
try {
143-
this.client = new Ollama({
143+
const clientOptions: any = {
144144
host: this.options.ollamaBaseUrl || "http://localhost:11434",
145145
// Note: The ollama npm package handles timeouts internally
146-
})
146+
}
147+
148+
// Add API key if provided (for Ollama cloud or authenticated instances)
149+
if (this.options.ollamaApiKey) {
150+
clientOptions.headers = {
151+
Authorization: `Bearer ${this.options.ollamaApiKey}`,
152+
}
153+
}
154+
155+
this.client = new Ollama(clientOptions)
147156
} catch (error: any) {
148157
throw new Error(`Error creating Ollama client: ${error.message}`)
149158
}

src/api/providers/ollama.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,20 @@ export class OllamaHandler extends BaseProvider implements SingleCompletionHandl
2525
super()
2626
this.options = options
2727

28+
// Use the API key if provided (for Ollama cloud or authenticated instances)
29+
// Otherwise use "ollama" as a placeholder for local instances
30+
const apiKey = this.options.ollamaApiKey || "ollama"
31+
32+
const headers: Record<string, string> = {}
33+
if (this.options.ollamaApiKey) {
34+
headers["Authorization"] = `Bearer ${this.options.ollamaApiKey}`
35+
}
36+
2837
this.client = new OpenAI({
2938
baseURL: (this.options.ollamaBaseUrl || "http://localhost:11434") + "/v1",
30-
apiKey: "ollama",
39+
apiKey: apiKey,
3140
timeout: getApiRequestTimeout(),
41+
defaultHeaders: headers,
3242
})
3343
}
3444

webview-ui/src/components/settings/providers/Ollama.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { useRouterModels } from "@src/components/ui/hooks/useRouterModels"
1111
import { vscode } from "@src/utils/vscode"
1212

1313
import { inputEventTransform } from "../transforms"
14+
import { ApiKeyField } from "../common/ApiKeyField"
1415

1516
type OllamaProps = {
1617
apiConfiguration: ProviderSettings
@@ -86,6 +87,15 @@ export const Ollama = ({ apiConfiguration, setApiConfigurationField }: OllamaPro
8687
className="w-full">
8788
<label className="block font-medium mb-1">{t("settings:providers.ollama.baseUrl")}</label>
8889
</VSCodeTextField>
90+
{apiConfiguration?.ollamaBaseUrl && (
91+
<ApiKeyField
92+
initialValue={apiConfiguration?.ollamaApiKey || ""}
93+
onChange={(value) => setApiConfigurationField("ollamaApiKey", value)}
94+
providerName="Ollama"
95+
placeholder={t("settings:placeholders.apiKey.ollama")}
96+
helpText={t("settings:providers.ollama.apiKeyHelp")}
97+
/>
98+
)}
8999
<VSCodeTextField
90100
value={apiConfiguration?.ollamaModelId || ""}
91101
onInput={handleInputChange("ollamaModelId")}

0 commit comments

Comments
 (0)