Skip to content

Commit 767abfe

Browse files
authored
feat(js/plugins/google-genai): Support urlContext for googleAI Gemini (#3822)
1 parent f639667 commit 767abfe

File tree

5 files changed

+43
-1
lines changed

5 files changed

+43
-1
lines changed

js/plugins/google-genai/src/common/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ export function isGoogleSearchRetrievalTool(
153153
);
154154
}
155155

156+
export declare interface UrlContextTool {
157+
urlContext?: {};
158+
}
159+
156160
/**
157161
* The FileSearch tool that retrieves knowledge from Semantic Retrieval corpora.
158162
* Files are imported to Semantic Retrieval corpora using the ImportFile API
@@ -935,6 +939,7 @@ export declare type Tool =
935939
| GoogleMapsTool // Vertex AI Only
936940
| CodeExecutionTool // Google AI Only
937941
| FileSearchTool // Google AI Only
942+
| UrlContextTool // Google AI Only
938943
| GoogleSearchRetrievalTool;
939944

940945
/**

js/plugins/google-genai/src/googleai/gemini.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import {
5252
SafetySetting,
5353
Tool,
5454
ToolConfig,
55+
UrlContextTool,
5556
} from './types.js';
5657
import {
5758
calculateApiKey,
@@ -221,6 +222,10 @@ export const GeminiConfigSchema = GenerationCommonConfigSchema.extend({
221222
})
222223
.passthrough()
223224
.optional(),
225+
urlContext: z
226+
.union([z.boolean(), z.object({}).passthrough()])
227+
.describe('Return grounding metadata from links included in the query')
228+
.optional(),
224229
temperature: z
225230
.number()
226231
.min(0)
@@ -567,6 +572,7 @@ export function defineModel(
567572
functionCallingConfig,
568573
googleSearchRetrieval,
569574
fileSearch,
575+
urlContext,
570576
tools: toolsFromConfig,
571577
...restOfConfigOptions
572578
} = requestOptions;
@@ -595,6 +601,12 @@ export function defineModel(
595601
});
596602
}
597603

604+
if (urlContext) {
605+
tools.push({
606+
urlContext: urlContext === true ? {} : urlContext,
607+
} as UrlContextTool);
608+
}
609+
598610
let toolConfig: ToolConfig | undefined;
599611
if (functionCallingConfig) {
600612
toolConfig = {

js/plugins/google-genai/src/googleai/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
TaskTypeSchema,
3737
Tool,
3838
ToolConfig,
39+
UrlContextTool,
3940
} from '../common/types.js';
4041

4142
// This makes it easier to import all types from one place.
@@ -60,6 +61,7 @@ export {
6061
type SafetySetting,
6162
type Tool,
6263
type ToolConfig,
64+
type UrlContextTool,
6365
};
6466

6567
export interface GoogleAIPluginOptions {

js/plugins/google-genai/tests/googleai/gemini_test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ describe('Google AI Gemini', () => {
282282
fileSearch: {
283283
fileSearchStoreNames: ['foo'],
284284
},
285+
urlContext: {},
285286
},
286287
};
287288
await model.run(request);
@@ -290,7 +291,7 @@ describe('Google AI Gemini', () => {
290291
fetchStub.lastCall.args[1].body
291292
);
292293
assert.ok(Array.isArray(apiRequest.tools));
293-
assert.strictEqual(apiRequest.tools?.length, 4);
294+
assert.strictEqual(apiRequest.tools?.length, 5);
294295
assert.deepStrictEqual(apiRequest.tools?.[1], { codeExecution: {} });
295296
assert.deepStrictEqual(apiRequest.tools?.[2], {
296297
googleSearch: {},
@@ -300,6 +301,9 @@ describe('Google AI Gemini', () => {
300301
fileSearchStoreNames: ['foo'],
301302
},
302303
});
304+
assert.deepStrictEqual(apiRequest.tools?.[4], {
305+
urlContext: {},
306+
});
303307
});
304308

305309
it('uses baseUrl and apiVersion from call config', async () => {

js/testapps/basic-gemini/src/index.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,25 @@ ai.defineFlow('search-grounding', async () => {
178178
};
179179
});
180180

181+
// Url context
182+
ai.defineFlow('url-context', async () => {
183+
const { text, raw } = await ai.generate({
184+
model: googleAI.model('gemini-2.5-flash'),
185+
prompt:
186+
'Compare the ingredients and cooking times from the recipes at ' +
187+
'https://www.foodnetwork.com/recipes/ina-garten/perfect-roast-chicken-recipe-1940592 ' +
188+
'and https://www.allrecipes.com/recipe/70679/simple-whole-roasted-chicken/',
189+
config: {
190+
urlContext: {},
191+
},
192+
});
193+
194+
return {
195+
text,
196+
groundingMetadata: (raw as any)?.candidates[0]?.groundingMetadata,
197+
};
198+
});
199+
181200
// File Search
182201
ai.defineFlow('file-search', async () => {
183202
// Use the google/genai SDK to upload the story BLOB to a new

0 commit comments

Comments
 (0)