Skip to content

Commit f276dad

Browse files
committed
Add url_context tool
1 parent b5132b3 commit f276dad

File tree

20 files changed

+103
-2
lines changed

20 files changed

+103
-2
lines changed

packages/types/src/provider-settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ const geminiSchema = apiModelIdProviderModelSchema.extend({
158158
geminiApiKey: z.string().optional(),
159159
googleGeminiBaseUrl: z.string().optional(),
160160
geminiEnableGoogleSearch: z.boolean().optional(),
161+
geminiEnableUrlContext: z.boolean().optional(),
161162
})
162163

163164
const geminiCliSchema = apiModelIdProviderModelSchema.extend({

src/api/providers/gemini.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,17 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl
6666
const { id: model, info, reasoning: thinkingConfig, maxTokens } = this.getModel()
6767

6868
const contents = messages.map(convertAnthropicMessageToGemini)
69+
const tools: GenerateContentConfig["tools"] = []
70+
if (this.options.geminiEnableGoogleSearch) {
71+
tools.push({ googleSearch: {} })
72+
}
73+
if (this.options.geminiEnableUrlContext) {
74+
tools.push({ urlContext: {} })
75+
}
76+
6977
const config: GenerateContentConfig = {
7078
systemInstruction,
71-
...(this.options.geminiEnableGoogleSearch && { tools: [{ googleSearch: {} }] }),
79+
...(tools.length > 0 && { tools }),
7280
httpOptions: this.options.googleGeminiBaseUrl ? { baseUrl: this.options.googleGeminiBaseUrl } : undefined,
7381
thinkingConfig,
7482
maxOutputTokens: this.options.modelMaxTokens ?? maxTokens ?? undefined,
@@ -145,12 +153,19 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl
145153
async completePrompt(prompt: string): Promise<string> {
146154
try {
147155
const { id: model, reasoning: thinkingConfig } = this.getModel()
156+
const tools: GenerateContentConfig["tools"] = []
157+
if (this.options.geminiEnableGoogleSearch) {
158+
tools.push({ googleSearch: {} })
159+
}
160+
if (this.options.geminiEnableUrlContext) {
161+
tools.push({ urlContext: {} })
162+
}
148163
const result = await this.client.models.generateContent({
149164
model,
150165
contents: [{ role: "user", parts: [{ text: prompt }] }],
151166
config: {
152167
thinkingConfig,
153-
...(this.options.geminiEnableGoogleSearch && { tools: [{ googleSearch: {} }] }),
168+
...(tools.length > 0 && { tools }),
154169
httpOptions: this.options.googleGeminiBaseUrl
155170
? { baseUrl: this.options.googleGeminiBaseUrl }
156171
: undefined,

src/core/prompts/tools/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { getInsertContentDescription } from "./insert-content"
1515
import { getSearchAndReplaceDescription } from "./search-and-replace"
1616
import { getListCodeDefinitionNamesDescription } from "./list-code-definition-names"
1717
import { getGoogleSearchDescription } from "./google-search"
18+
import { getUrlContextDescription } from "./url-context"
1819
import { getBrowserActionDescription } from "./browser-action"
1920
import { getAskFollowupQuestionDescription } from "./ask-followup-question"
2021
import { getAttemptCompletionDescription } from "./attempt-completion"
@@ -45,6 +46,7 @@ const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined>
4546
insert_content: (args) => getInsertContentDescription(args),
4647
search_and_replace: (args) => getSearchAndReplaceDescription(args),
4748
google_search: (args) => getGoogleSearchDescription(args),
49+
url_context: (args) => getUrlContextDescription(args),
4850
apply_diff: (args) =>
4951
args.diffStrategy ? args.diffStrategy.getToolDescription({ cwd: args.cwd, toolOptions: args.toolOptions }) : "",
5052
}
@@ -112,6 +114,9 @@ export function getToolDescriptionsForMode(
112114
if (settings?.geminiEnableGoogleSearch) {
113115
tools.add("google_search")
114116
}
117+
if (settings?.geminiEnableUrlContext) {
118+
tools.add("url_context")
119+
}
115120

116121
// Map tool descriptions for allowed tools
117122
const descriptions = Array.from(tools).map((toolName) => {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { ToolArgs } from "./types"
2+
3+
export function getUrlContextDescription(args: ToolArgs): string {
4+
return `
5+
# url_context
6+
Description: When you need to retrieve content from a URL to inform your response, you can use this tool.
7+
`
8+
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ export const Gemini = ({ apiConfiguration, setApiConfigurationField }: GeminiPro
6262
</span>
6363
</div>
6464
</Checkbox>
65+
<Checkbox
66+
checked={!!apiConfiguration.geminiEnableUrlContext}
67+
onChange={(checked: boolean) => {
68+
setApiConfigurationField("geminiEnableUrlContext", checked)
69+
}}>
70+
<div className="flex flex-col">
71+
<span className="font-medium">{t("settings:providers.geminiEnableUrlContext.label")}</span>
72+
<span className="text-sm text-vscode-descriptionForeground">
73+
{t("settings:providers.geminiEnableUrlContext.description")}
74+
</span>
75+
</div>
76+
</Checkbox>
6577
<div>
6678
<Checkbox
6779
checked={googleGeminiBaseUrlSelected}

webview-ui/src/i18n/locales/ca/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@
225225
"label": "Activa la Cerca de Google",
226226
"description": "Permet al model utilitzar la Cerca de Google per respondre preguntes sobre esdeveniments recents. Això pot comportar costos addicionals i és mútuament excloent amb la funció de 'pensament'."
227227
},
228+
"geminiEnableUrlContext": {
229+
"label": "Enable URL Context",
230+
"description": "Allows the model to retrieve content from URLs provided in the prompt to inform its response."
231+
},
228232
"getGroqApiKey": "Obtenir clau API de Groq",
229233
"groqApiKey": "Clau API de Groq",
230234
"getGeminiApiKey": "Obtenir clau API de Gemini",

webview-ui/src/i18n/locales/de/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@
225225
"label": "Google Suche aktivieren",
226226
"description": "Ermöglicht dem Modell, die Google-Suche zu verwenden, um Fragen zu aktuellen Ereignissen zu beantworten. Dies kann zusätzliche Kosten verursachen und ist mit der 'Denk'-Funktion nicht kompatibel."
227227
},
228+
"geminiEnableUrlContext": {
229+
"label": "URL-Kontext aktivieren",
230+
"description": "Ermöglicht dem Modell, Inhalte von in der Eingabeaufforderung bereitgestellten URLs abzurufen, um seine Antwort zu informieren."
231+
},
228232
"getGroqApiKey": "Groq API-Schlüssel erhalten",
229233
"groqApiKey": "Groq API-Schlüssel",
230234
"getGeminiApiKey": "Gemini API-Schlüssel erhalten",

webview-ui/src/i18n/locales/en/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@
225225
"label": "Enable Google Search",
226226
"description": "Allows the model to use Google Search to answer questions about recent events. This may incur additional costs and is mutually exclusive with the 'thinking' feature."
227227
},
228+
"geminiEnableUrlContext": {
229+
"label": "Enable URL Context",
230+
"description": "Allows the model to retrieve content from URLs provided in the prompt to inform its response."
231+
},
228232
"getGroqApiKey": "Get Groq API Key",
229233
"groqApiKey": "Groq API Key",
230234
"getGeminiApiKey": "Get Gemini API Key",

webview-ui/src/i18n/locales/es/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@
225225
"label": "Habilitar Búsqueda de Google",
226226
"description": "Permite al modelo usar la Búsqueda de Google para responder preguntas sobre eventos recientes. Esto puede incurrir en costos adicionales y es mutuamente excluyente con la función de 'pensamiento'."
227227
},
228+
"geminiEnableUrlContext": {
229+
"label": "Habilitar contexto de URL",
230+
"description": "Permite que el modelo recupere contenido de las URL proporcionadas en el aviso para informar su respuesta."
231+
},
228232
"getGroqApiKey": "Obtener clave API de Groq",
229233
"groqApiKey": "Clave API de Groq",
230234
"getGeminiApiKey": "Obtener clave API de Gemini",

webview-ui/src/i18n/locales/fr/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@
225225
"label": "Activer la recherche Google",
226226
"description": "Permet au modèle d'utiliser la recherche Google pour répondre aux questions sur les événements récents. Cela peut entraîner des coûts supplémentaires et est mutuellement exclusif avec la fonction de 'réflexion'."
227227
},
228+
"geminiEnableUrlContext": {
229+
"label": "Activer le contexte d'URL",
230+
"description": "Permet au modèle de récupérer le contenu des URL fournies dans l'invite pour éclairer sa réponse."
231+
},
228232
"getGroqApiKey": "Obtenir la clé API Groq",
229233
"groqApiKey": "Clé API Groq",
230234
"getGeminiApiKey": "Obtenir la clé API Gemini",

0 commit comments

Comments
 (0)