Skip to content

Commit ad2256c

Browse files
committed
Add URL Context tool
1 parent 1d94cf6 commit ad2256c

File tree

3 files changed

+81
-33
lines changed

3 files changed

+81
-33
lines changed

ai/ai-react-app/src/components/Layout/RightSidebar.tsx

Lines changed: 70 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
AVAILABLE_IMAGEN_MODELS,
77
defaultFunctionCallingTool,
88
defaultGoogleSearchTool,
9+
defaultURLContextTool,
910
} from "../../services/firebaseAIService";
1011
import {
1112
ModelParams,
@@ -160,17 +161,36 @@ const RightSidebar: React.FC<RightSidebarProps> = ({
160161
nextState.toolConfig = undefined; // Clear config when turning off
161162
}
162163
} else if (name === "google-search-toggle") {
164+
const otherTools = (prev.tools || []).filter(
165+
(tool) => !("googleSearch" in tool),
166+
);
163167
if (checked) {
164168
// Turn ON Google Search Grounding
165-
nextState.tools = [defaultGoogleSearchTool];
169+
nextState.tools = [...otherTools, defaultGoogleSearchTool];
166170

167171
// Turn OFF JSON mode and Function Calling
168172
nextState.generationConfig.responseMimeType = undefined;
169173
nextState.generationConfig.responseSchema = undefined;
170174
nextState.toolConfig = undefined;
171175
} else {
172176
// Turn OFF Google Search Grounding
173-
nextState.tools = undefined;
177+
nextState.tools = otherTools.length > 0 ? otherTools : undefined;
178+
}
179+
} else if (name === "url-context-toggle") {
180+
const otherTools = (prev.tools || []).filter(
181+
(tool) => !("urlContext" in tool),
182+
);
183+
if (checked) {
184+
// Turn ON URL Context
185+
nextState.tools = [...otherTools, defaultURLContextTool];
186+
187+
// Turn OFF JSON mode and Function Calling
188+
nextState.generationConfig.responseMimeType = undefined;
189+
nextState.generationConfig.responseSchema = undefined;
190+
nextState.toolConfig = undefined;
191+
} else {
192+
// Turn OFF URL Context
193+
nextState.tools = otherTools.length > 0 ? otherTools : undefined;
174194
}
175195
}
176196
console.log("[RightSidebar] Updated generative params state:", nextState);
@@ -227,15 +247,14 @@ const RightSidebar: React.FC<RightSidebarProps> = ({
227247
// Derive UI state from config
228248
const isStructuredOutputActive =
229249
generativeParams.generationConfig?.responseMimeType === "application/json";
230-
const isFunctionCallingActive =
231-
(generativeParams.toolConfig?.functionCallingConfig?.mode ===
232-
FunctionCallingMode.AUTO ||
233-
generativeParams.toolConfig?.functionCallingConfig?.mode ===
234-
FunctionCallingMode.ANY) &&
235-
!!generativeParams.tools?.length;
250+
const isFunctionCallingActive = !!generativeParams.toolConfig
251+
?.functionCallingConfig;
236252
const isGroundingWithGoogleSearchActive = !!generativeParams.tools?.some(
237253
(tool) => "googleSearch" in tool,
238254
);
255+
const isURLContextActive = !!generativeParams.tools?.some(
256+
(tool) => "urlContext" in tool,
257+
);
239258

240259
return (
241260
<div className={styles.rightSidebarContainer}>
@@ -365,7 +384,13 @@ const RightSidebar: React.FC<RightSidebarProps> = ({
365384
<div>
366385
<h5 className={styles.subSectionTitle}>Tools</h5>
367386
<div
368-
className={`${styles.toggleGroup} ${isFunctionCallingActive ? styles.disabledText : ""}`}
387+
className={`${styles.toggleGroup} ${
388+
isFunctionCallingActive ||
389+
isGroundingWithGoogleSearchActive ||
390+
isURLContextActive
391+
? styles.disabledText
392+
: ""
393+
}`}
369394
>
370395
<label htmlFor="structured-output-toggle">
371396
Structured output (JSON)
@@ -378,16 +403,22 @@ const RightSidebar: React.FC<RightSidebarProps> = ({
378403
checked={isStructuredOutputActive}
379404
onChange={handleToggleChange}
380405
disabled={
381-
isFunctionCallingActive || isGroundingWithGoogleSearchActive
406+
isFunctionCallingActive ||
407+
isGroundingWithGoogleSearchActive ||
408+
isURLContextActive
382409
}
383410
/>
384-
<span
385-
className={`${styles.slider} ${isFunctionCallingActive || isGroundingWithGoogleSearchActive ? styles.disabled : ""}`}
386-
></span>
411+
<span className={styles.slider}></span>
387412
</label>
388413
</div>
389414
<div
390-
className={`${styles.toggleGroup} ${isStructuredOutputActive || isGroundingWithGoogleSearchActive ? styles.disabledText : ""}`}
415+
className={`${styles.toggleGroup} ${
416+
isStructuredOutputActive ||
417+
isGroundingWithGoogleSearchActive ||
418+
isURLContextActive
419+
? styles.disabledText
420+
: ""
421+
}`}
391422
>
392423
<label htmlFor="function-call-toggle">Function calling</label>
393424
<label className={styles.switch}>
@@ -399,12 +430,11 @@ const RightSidebar: React.FC<RightSidebarProps> = ({
399430
onChange={handleToggleChange}
400431
disabled={
401432
isStructuredOutputActive ||
402-
isGroundingWithGoogleSearchActive
433+
isGroundingWithGoogleSearchActive ||
434+
isURLContextActive
403435
}
404436
/>
405-
<span
406-
className={`${styles.slider} ${isStructuredOutputActive ? styles.disabled : ""}`}
407-
></span>
437+
<span className={styles.slider}></span>
408438
</label>
409439
</div>
410440
<div
@@ -426,13 +456,27 @@ const RightSidebar: React.FC<RightSidebarProps> = ({
426456
onChange={handleToggleChange}
427457
disabled={isStructuredOutputActive || isFunctionCallingActive}
428458
/>
429-
<span
430-
className={`${styles.slider} ${
431-
isStructuredOutputActive || isFunctionCallingActive
432-
? styles.disabled
433-
: ""
434-
}`}
435-
></span>
459+
<span className={styles.slider}></span>
460+
</label>
461+
</div>
462+
<div
463+
className={`${styles.toggleGroup} ${
464+
isStructuredOutputActive || isFunctionCallingActive
465+
? styles.disabledText
466+
: ""
467+
}`}
468+
>
469+
<label htmlFor="url-context-toggle">URL Context</label>
470+
<label className={styles.switch}>
471+
<input
472+
type="checkbox"
473+
id="url-context-toggle"
474+
name="url-context-toggle"
475+
checked={isURLContextActive}
476+
onChange={handleToggleChange}
477+
disabled={isStructuredOutputActive || isFunctionCallingActive}
478+
/>
479+
<span className={styles.slider}></span>
436480
</label>
437481
</div>
438482
</div>
@@ -519,4 +563,4 @@ const RightSidebar: React.FC<RightSidebarProps> = ({
519563
);
520564
};
521565

522-
export default RightSidebar;
566+
export default RightSidebar;

ai/ai-react-app/src/services/firebaseAIService.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ import {
1313
FunctionCall,
1414
GoogleSearchTool,
1515
BackendType,
16+
URLContextTool,
1617
} from "firebase/ai";
1718

1819
import { firebaseConfig } from "../config/firebase-config";
1920

2021
export const AVAILABLE_GENERATIVE_MODELS = [
22+
"gemini-2.5-flash",
2123
"gemini-2.0-flash",
2224
"gemini-2.0-flash-lite",
23-
"gemini-2.0-flash-exp",
24-
"gemini-2.5-flash"
2525
];
2626
export const AVAILABLE_IMAGEN_MODELS = ["imagen-3.0-generate-002"];
2727
export const LIVE_MODELS = new Map<BackendType, string>([
@@ -65,8 +65,12 @@ export const defaultFunctionCallingTool = {
6565
};
6666

6767
export const defaultGoogleSearchTool: GoogleSearchTool = {
68-
googleSearch: {}
69-
}
68+
googleSearch: {},
69+
};
70+
71+
export const defaultURLContextTool: URLContextTool = {
72+
urlContext: {},
73+
};
7074

7175
export const defaultGenerativeParams: Omit<ModelParams, "model"> = {
7276
// Model name itself is selected in the UI
@@ -116,7 +120,7 @@ export const handleFunctionExecution = async (
116120
await new Promise((resolve) => setTimeout(resolve, 800)); // Simulate delay
117121
const location: string =
118122
"location" in functionCall.args &&
119-
typeof functionCall.args.location === "string"
123+
typeof functionCall.args.location === "string"
120124
? functionCall.args.location
121125
: "Default City, ST";
122126
const unit: string =

ai/ai-react-app/src/views/ChatView.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ const ChatView: React.FC<ChatViewProps> = ({
134134
const suggestions = [
135135
"Explain the difference between `let`, `const`, and `var` in JavaScript.",
136136
"Write a short story about a friendly robot.",
137-
"Describe this image.",
137+
"Summarize this page: https://en.wikipedia.org/wiki/Galatea_of_the_Spheres",
138138
"What's the weather in London in Celsius?",
139139
];
140140
const handleSuggestion = (suggestion: string) => {
@@ -548,4 +548,4 @@ const ChatView: React.FC<ChatViewProps> = ({
548548
);
549549
};
550550

551-
export default ChatView;
551+
export default ChatView;

0 commit comments

Comments
 (0)