diff --git a/ai/ai-react-app/src/components/Layout/RightSidebar.tsx b/ai/ai-react-app/src/components/Layout/RightSidebar.tsx index 9e703ee35..c4e644ebd 100644 --- a/ai/ai-react-app/src/components/Layout/RightSidebar.tsx +++ b/ai/ai-react-app/src/components/Layout/RightSidebar.tsx @@ -6,6 +6,7 @@ import { AVAILABLE_IMAGEN_MODELS, defaultFunctionCallingTool, defaultGoogleSearchTool, + defaultURLContextTool, } from "../../services/firebaseAIService"; import { ModelParams, @@ -160,9 +161,12 @@ const RightSidebar: React.FC = ({ nextState.toolConfig = undefined; // Clear config when turning off } } else if (name === "google-search-toggle") { + const otherTools = (prev.tools || []).filter( + (tool) => !("googleSearch" in tool), + ); if (checked) { // Turn ON Google Search Grounding - nextState.tools = [defaultGoogleSearchTool]; + nextState.tools = [...otherTools, defaultGoogleSearchTool]; // Turn OFF JSON mode and Function Calling nextState.generationConfig.responseMimeType = undefined; @@ -170,7 +174,23 @@ const RightSidebar: React.FC = ({ nextState.toolConfig = undefined; } else { // Turn OFF Google Search Grounding - nextState.tools = undefined; + nextState.tools = otherTools.length > 0 ? otherTools : undefined; + } + } else if (name === "url-context-toggle") { + const otherTools = (prev.tools || []).filter( + (tool) => !("urlContext" in tool), + ); + if (checked) { + // Turn ON URL Context + nextState.tools = [...otherTools, defaultURLContextTool]; + + // Turn OFF JSON mode and Function Calling + nextState.generationConfig.responseMimeType = undefined; + nextState.generationConfig.responseSchema = undefined; + nextState.toolConfig = undefined; + } else { + // Turn OFF URL Context + nextState.tools = otherTools.length > 0 ? otherTools : undefined; } } console.log("[RightSidebar] Updated generative params state:", nextState); @@ -227,15 +247,14 @@ const RightSidebar: React.FC = ({ // Derive UI state from config const isStructuredOutputActive = generativeParams.generationConfig?.responseMimeType === "application/json"; - const isFunctionCallingActive = - (generativeParams.toolConfig?.functionCallingConfig?.mode === - FunctionCallingMode.AUTO || - generativeParams.toolConfig?.functionCallingConfig?.mode === - FunctionCallingMode.ANY) && - !!generativeParams.tools?.length; + const isFunctionCallingActive = !!generativeParams.toolConfig + ?.functionCallingConfig; const isGroundingWithGoogleSearchActive = !!generativeParams.tools?.some( (tool) => "googleSearch" in tool, ); + const isURLContextActive = !!generativeParams.tools?.some( + (tool) => "urlContext" in tool, + ); return (
@@ -365,7 +384,13 @@ const RightSidebar: React.FC = ({
Tools
= ({ onChange={handleToggleChange} disabled={isStructuredOutputActive || isFunctionCallingActive} /> - + + +
+
+ +
@@ -519,4 +563,4 @@ const RightSidebar: React.FC = ({ ); }; -export default RightSidebar; +export default RightSidebar; \ No newline at end of file diff --git a/ai/ai-react-app/src/services/firebaseAIService.ts b/ai/ai-react-app/src/services/firebaseAIService.ts index 435560a8e..6e0893d09 100644 --- a/ai/ai-react-app/src/services/firebaseAIService.ts +++ b/ai/ai-react-app/src/services/firebaseAIService.ts @@ -13,15 +13,15 @@ import { FunctionCall, GoogleSearchTool, BackendType, + URLContextTool, } from "firebase/ai"; import { firebaseConfig } from "../config/firebase-config"; export const AVAILABLE_GENERATIVE_MODELS = [ + "gemini-2.5-flash", "gemini-2.0-flash", "gemini-2.0-flash-lite", - "gemini-2.0-flash-exp", - "gemini-2.5-flash" ]; export const AVAILABLE_IMAGEN_MODELS = ["imagen-3.0-generate-002"]; export const LIVE_MODELS = new Map([ @@ -65,8 +65,12 @@ export const defaultFunctionCallingTool = { }; export const defaultGoogleSearchTool: GoogleSearchTool = { - googleSearch: {} -} + googleSearch: {}, +}; + +export const defaultURLContextTool: URLContextTool = { + urlContext: {}, +}; export const defaultGenerativeParams: Omit = { // Model name itself is selected in the UI @@ -116,7 +120,7 @@ export const handleFunctionExecution = async ( await new Promise((resolve) => setTimeout(resolve, 800)); // Simulate delay const location: string = "location" in functionCall.args && - typeof functionCall.args.location === "string" + typeof functionCall.args.location === "string" ? functionCall.args.location : "Default City, ST"; const unit: string = diff --git a/ai/ai-react-app/src/views/ChatView.tsx b/ai/ai-react-app/src/views/ChatView.tsx index f2dd7dd17..906e12ef2 100644 --- a/ai/ai-react-app/src/views/ChatView.tsx +++ b/ai/ai-react-app/src/views/ChatView.tsx @@ -134,7 +134,7 @@ const ChatView: React.FC = ({ const suggestions = [ "Explain the difference between `let`, `const`, and `var` in JavaScript.", "Write a short story about a friendly robot.", - "Describe this image.", + "Summarize this page: https://en.wikipedia.org/wiki/Galatea_of_the_Spheres", "What's the weather in London in Celsius?", ]; const handleSuggestion = (suggestion: string) => { @@ -548,4 +548,4 @@ const ChatView: React.FC = ({ ); }; -export default ChatView; +export default ChatView; \ No newline at end of file