support custom base url for gemini in google AI studio

This commit is contained in:
dongqing 2025-03-10 19:06:58 +08:00
parent 30c1c2549a
commit 85b54b33ba
4 changed files with 51 additions and 7 deletions

View file

@ -17,10 +17,15 @@ export class GeminiHandler implements ApiHandler, SingleCompletionHandler {
}
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
const model = this.client.getGenerativeModel({
model: this.getModel().id,
systemInstruction: systemPrompt,
})
const model = this.client.getGenerativeModel(
{
model: this.getModel().id,
systemInstruction: systemPrompt,
},
{
baseUrl: this.options.googleGeminiBaseUrl || undefined,
},
)
const result = await model.generateContentStream({
contents: messages.map(convertAnthropicMessageToGemini),
generationConfig: {
@ -55,9 +60,14 @@ export class GeminiHandler implements ApiHandler, SingleCompletionHandler {
async completePrompt(prompt: string): Promise<string> {
try {
const model = this.client.getGenerativeModel({
model: this.getModel().id,
})
const model = this.client.getGenerativeModel(
{
model: this.getModel().id,
},
{
baseUrl: this.options.googleGeminiBaseUrl || undefined,
},
)
const result = await model.generateContent({
contents: [{ role: "user", parts: [{ text: prompt }] }],

View file

@ -96,6 +96,7 @@ type GlobalStateKey =
| "openRouterModelInfo"
| "openRouterBaseUrl"
| "openRouterUseMiddleOutTransform"
| "googleGeminiBaseUrl"
| "allowedCommands"
| "soundEnabled"
| "soundVolume"
@ -1657,6 +1658,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
anthropicBaseUrl,
anthropicThinking,
geminiApiKey,
googleGeminiBaseUrl,
openAiNativeApiKey,
deepSeekApiKey,
azureApiVersion,
@ -1704,6 +1706,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
this.updateGlobalState("lmStudioBaseUrl", lmStudioBaseUrl),
this.updateGlobalState("anthropicBaseUrl", anthropicBaseUrl),
this.updateGlobalState("anthropicThinking", anthropicThinking),
this.updateGlobalState("googleGeminiBaseUrl", googleGeminiBaseUrl),
this.storeSecret("geminiApiKey", geminiApiKey),
this.storeSecret("openAiNativeApiKey", openAiNativeApiKey),
this.storeSecret("deepSeekApiKey", deepSeekApiKey),
@ -2516,6 +2519,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
anthropicBaseUrl,
anthropicThinking,
geminiApiKey,
googleGeminiBaseUrl,
openAiNativeApiKey,
deepSeekApiKey,
mistralApiKey,
@ -2598,6 +2602,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
this.getGlobalState("lmStudioBaseUrl") as Promise<string | undefined>,
this.getGlobalState("anthropicBaseUrl") as Promise<string | undefined>,
this.getGlobalState("anthropicThinking") as Promise<number | undefined>,
this.getGlobalState("googleGeminiBaseUrl") as Promise<string | undefined>,
this.getSecret("geminiApiKey") as Promise<string | undefined>,
this.getSecret("openAiNativeApiKey") as Promise<string | undefined>,
this.getSecret("deepSeekApiKey") as Promise<string | undefined>,
@ -2699,6 +2704,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
anthropicBaseUrl,
anthropicThinking,
geminiApiKey,
googleGeminiBaseUrl,
openAiNativeApiKey,
deepSeekApiKey,
mistralApiKey,

View file

@ -51,6 +51,7 @@ export interface ApiHandlerOptions {
lmStudioModelId?: string
lmStudioBaseUrl?: string
geminiApiKey?: string
googleGeminiBaseUrl?: string
openAiNativeApiKey?: string
mistralApiKey?: string
mistralCodestralUrl?: string // New option for Codestral URL

View file

@ -71,6 +71,9 @@ const ApiOptions = ({
const [anthropicThinkingBudget, setAnthropicThinkingBudget] = useState(apiConfiguration?.anthropicThinking)
const [azureApiVersionSelected, setAzureApiVersionSelected] = useState(!!apiConfiguration?.azureApiVersion)
const [openRouterBaseUrlSelected, setOpenRouterBaseUrlSelected] = useState(!!apiConfiguration?.openRouterBaseUrl)
const [googleGeminiBaseUrlSelected, setGoogleGeminiBaseUrlSelected] = useState(
!!apiConfiguration?.googleGeminiBaseUrl,
)
const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false)
const inputEventTransform = <E,>(event: E) => (event as { target: HTMLInputElement })?.target?.value as any
@ -574,6 +577,30 @@ const ApiOptions = ({
placeholder="Enter API Key...">
<span style={{ fontWeight: 500 }}>Gemini API Key</span>
</VSCodeTextField>
<Checkbox
checked={googleGeminiBaseUrlSelected}
onChange={(checked: boolean) => {
setGoogleGeminiBaseUrlSelected(checked)
if (!checked) {
handleInputChange("googleGeminiBaseUrl")({
target: {
value: "",
},
})
}
}}>
Use custom base URL
</Checkbox>
{googleGeminiBaseUrlSelected && (
<VSCodeTextField
value={apiConfiguration?.googleGeminiBaseUrl || ""}
style={{ width: "100%", marginTop: 3 }}
type="url"
onInput={handleInputChange("googleGeminiBaseUrl")}
placeholder="Default: https://generativelanguage.googleapis.com"
/>
)}
<p
style={{
fontSize: "12px",