Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 70 additions & 26 deletions ai/ai-react-app/src/components/Layout/RightSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
AVAILABLE_IMAGEN_MODELS,
defaultFunctionCallingTool,
defaultGoogleSearchTool,
defaultURLContextTool,
} from "../../services/firebaseAIService";
import {
ModelParams,
Expand Down Expand Up @@ -160,17 +161,36 @@ const RightSidebar: React.FC<RightSidebarProps> = ({
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;
nextState.generationConfig.responseSchema = undefined;
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);
Expand Down Expand Up @@ -227,15 +247,14 @@ const RightSidebar: React.FC<RightSidebarProps> = ({
// 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 (
<div className={styles.rightSidebarContainer}>
Expand Down Expand Up @@ -365,7 +384,13 @@ const RightSidebar: React.FC<RightSidebarProps> = ({
<div>
<h5 className={styles.subSectionTitle}>Tools</h5>
<div
className={`${styles.toggleGroup} ${isFunctionCallingActive ? styles.disabledText : ""}`}
className={`${styles.toggleGroup} ${
isFunctionCallingActive ||
isGroundingWithGoogleSearchActive ||
isURLContextActive
? styles.disabledText
: ""
}`}
>
<label htmlFor="structured-output-toggle">
Structured output (JSON)
Expand All @@ -378,16 +403,22 @@ const RightSidebar: React.FC<RightSidebarProps> = ({
checked={isStructuredOutputActive}
onChange={handleToggleChange}
disabled={
isFunctionCallingActive || isGroundingWithGoogleSearchActive
isFunctionCallingActive ||
isGroundingWithGoogleSearchActive ||
isURLContextActive
}
/>
<span
className={`${styles.slider} ${isFunctionCallingActive || isGroundingWithGoogleSearchActive ? styles.disabled : ""}`}
></span>
<span className={styles.slider}></span>
</label>
</div>
<div
className={`${styles.toggleGroup} ${isStructuredOutputActive || isGroundingWithGoogleSearchActive ? styles.disabledText : ""}`}
className={`${styles.toggleGroup} ${
isStructuredOutputActive ||
isGroundingWithGoogleSearchActive ||
isURLContextActive
? styles.disabledText
: ""
}`}
>
<label htmlFor="function-call-toggle">Function calling</label>
<label className={styles.switch}>
Expand All @@ -399,12 +430,11 @@ const RightSidebar: React.FC<RightSidebarProps> = ({
onChange={handleToggleChange}
disabled={
isStructuredOutputActive ||
isGroundingWithGoogleSearchActive
isGroundingWithGoogleSearchActive ||
isURLContextActive
}
/>
<span
className={`${styles.slider} ${isStructuredOutputActive ? styles.disabled : ""}`}
></span>
<span className={styles.slider}></span>
</label>
</div>
<div
Expand All @@ -426,13 +456,27 @@ const RightSidebar: React.FC<RightSidebarProps> = ({
onChange={handleToggleChange}
disabled={isStructuredOutputActive || isFunctionCallingActive}
/>
<span
className={`${styles.slider} ${
isStructuredOutputActive || isFunctionCallingActive
? styles.disabled
: ""
}`}
></span>
<span className={styles.slider}></span>
</label>
</div>
<div
className={`${styles.toggleGroup} ${
isStructuredOutputActive || isFunctionCallingActive
? styles.disabledText
: ""
}`}
>
<label htmlFor="url-context-toggle">URL Context</label>
<label className={styles.switch}>
<input
type="checkbox"
id="url-context-toggle"
name="url-context-toggle"
checked={isURLContextActive}
onChange={handleToggleChange}
disabled={isStructuredOutputActive || isFunctionCallingActive}
/>
<span className={styles.slider}></span>
</label>
</div>
</div>
Expand Down Expand Up @@ -519,4 +563,4 @@ const RightSidebar: React.FC<RightSidebarProps> = ({
);
};

export default RightSidebar;
export default RightSidebar;
14 changes: 9 additions & 5 deletions ai/ai-react-app/src/services/firebaseAIService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<BackendType, string>([
Expand Down Expand Up @@ -65,8 +65,12 @@ export const defaultFunctionCallingTool = {
};

export const defaultGoogleSearchTool: GoogleSearchTool = {
googleSearch: {}
}
googleSearch: {},
};

export const defaultURLContextTool: URLContextTool = {
urlContext: {},
};

export const defaultGenerativeParams: Omit<ModelParams, "model"> = {
// Model name itself is selected in the UI
Expand Down Expand Up @@ -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 =
Expand Down
4 changes: 2 additions & 2 deletions ai/ai-react-app/src/views/ChatView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ const ChatView: React.FC<ChatViewProps> = ({
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) => {
Expand Down Expand Up @@ -548,4 +548,4 @@ const ChatView: React.FC<ChatViewProps> = ({
);
};

export default ChatView;
export default ChatView;
Loading