Feat/ai samples function calling final - #1076
Conversation
Wiz Scan Summary
To detect these findings earlier in the dev lifecycle, try the Wiz Code extension for VS Code, JetBrains, or Visual Studio. |
There was a problem hiding this comment.
Code Review
This pull request introduces a modular React and Vite-based sample application demonstrating various Firebase AI capabilities, including text generation, multi-turn chat, and function calling. The code review highlights several critical issues that need to be addressed: multiple instances of invalid Gemini model names (such as 'gemini-3.5-flash' and 'gemini-3.6-flash') that will cause runtime errors, incorrect types and redundant configuration for model tools, and top-level await statements in the function calling service that trigger side-effects on import and break ES2020 compilation. Additionally, the reviewer recommends wiring the static function calling UI to its service, resolving an unclosed code block in the README, and dynamically configuring the App Check debug token via environment variables instead of hardcoding it.
I am having trouble creating individual review comments. Click here to see my feedback.
ai/ai-samples/src/services/firebaseAIService.ts (34)
The default model name is set to 'gemini-3.5-flash', which is not a valid Gemini model name and will cause runtime API errors. Please use a valid model name such as 'gemini-1.5-flash' or 'gemini-2.0-flash'.
export const getAiModel = (modelName: string = 'gemini-1.5-flash', additionalConfig: Record<string, any> = {}) => {
ai/ai-samples/src/features/chat/service.ts (11)
The model name 'gemini-3.5-flash' does not exist and will fail at runtime. Please use a valid model name like 'gemini-1.5-flash'.
const model = getAiModel('gemini-1.5-flash');
ai/ai-samples/src/features/text-generation/service.ts (10)
The model name 'gemini-3.5-flash' does not exist and will fail at runtime. Please use a valid model name like 'gemini-1.5-flash'.
const model = getAiModel('gemini-1.5-flash');
ai/ai-samples/src/features/text-generation/service.ts (27)
The model name 'gemini-3.5-flash' does not exist and will fail at runtime. Please use a valid model name like 'gemini-1.5-flash'.
const model = getAiModel('gemini-1.5-flash');
ai/ai-samples/src/features/text-generation/service.ts (50)
The model name 'gemini-3.5-flash' does not exist and will fail at runtime. Please use a valid model name like 'gemini-1.5-flash'.
const model = getAiModel('gemini-1.5-flash', { systemInstruction });
ai/ai-samples/src/features/function-calling/service.ts (65-69)
The model name 'gemini-3.6-flash' does not exist and will fail at runtime. Additionally, passing model inside the config object is redundant since it is already passed as the first argument. Also, tools should be an array of tools rather than a single tool object to comply with the SDK's expected types.
const model = getAiModel('gemini-1.5-flash', {
// Provide the function declaration to the model.
tools: [fetchWeatherTool]
});ai/ai-samples/src/features/function-calling/service.ts (74-109)
This file executes API calls and uses top-level await directly at the module level. This causes side-effects immediately upon importing the file, and will fail compilation when targeting ES2020 (as configured in tsconfig.json). Wrapping this execution logic in an exportable async function prevents side-effects on import, resolves compilation errors, and allows the UI to trigger the demo.
export async function runWeatherDemo(): Promise<string> {
const chat = model.startChat();
const prompt = "What was the weather in Boston on October 17, 2024?";
// Send the user's question (the prompt) to the model using multi-turn chat.
let result = await chat.sendMessage(prompt);
const functionCalls = result.response.functionCalls() ?? [];
let functionCall;
let functionResult;
// When the model responds with one or more function calls, invoke the function(s).
if (functionCalls.length > 0) {
for (const call of functionCalls) {
if (call.name === "fetchWeather") {
// Forward the structured input data prepared by the model
// to the hypothetical external API.
functionResult = await fetchWeather(call.args as { location: { city: string; state: string }; date: string });
functionCall = call;
}
}
}
/**
* Step 5: Send the response from the function back to the model
* so that the model can use it to generate its final response.
*/
if (functionCall && functionResult) {
result = await chat.sendMessage([
{
functionResponse: {
name: functionCall.name, // "fetchWeather"
response: functionResult,
},
},
]);
}
const responseText = result.response.text();
console.log(responseText);
return responseText;
}ai/ai-samples/src/features/function-calling/index.tsx (1-9)
The Function Calling feature UI is currently a static placeholder that only renders a header. We should wire it up to the runWeatherDemo service function so that users can actually run the demo and see the function calling results in the browser.
import React, { useState } from 'react';
import { runWeatherDemo } from './service';
export default function FunctionCallingFeature() {
const [result, setResult] = useState<string>('');
const [loading, setLoading] = useState<boolean>(false);
const [error, setError] = useState<string | null>(null);
const handleRunDemo = async () => {
setLoading(true);
setError(null);
setResult('');
try {
const text = await runWeatherDemo();
setResult(text);
} catch (err: any) {
setError(err.message || 'An error occurred');
} finally {
setLoading(false);
}
};
return (
<div style={{ padding: '20px', maxWidth: '600px', margin: '0 auto' }}>
<h2>Function Calling</h2>
<p>Ask the model: "What was the weather in Boston on October 17, 2024?"</p>
<button onClick={handleRunDemo} disabled={loading} style={{ padding: '10px 20px' }}>
{loading ? 'Running Demo...' : 'Run Weather Demo'}
</button>
{error && <p style={{ color: 'red', marginTop: '15px' }}>{error}</p>}
{result && (
<div style={{ marginTop: '20px', padding: '15px', backgroundColor: '#f0f0f0' }}>
<p style={{ whiteSpace: 'pre-wrap' }}>{result}</p>
</div>
)}
</div>
);
}
ai/ai-samples/README.md (21-23)
The code block starting at line 22 is never closed with triple backticks, which will break the markdown rendering of the rest of the README document.
1. Navigate to this directory and install dependencies:
```bash
npm install
### ai/ai-samples/src/services/firebaseAIService.ts (20-21)

The App Check debug token is hardcoded to `true`, which bypasses the environment variable configuration mentioned in the README (`VITE_APPCHECK_DEBUG_TOKEN=true`). It is better to dynamically enable it based on the environment variable.
```typescript
if (typeof window !== 'undefined') {
if (import.meta.env.VITE_APPCHECK_DEBUG_TOKEN === 'true') {
(window as any).FIREBASE_APPCHECK_DEBUG_TOKEN = true;
}
No description provided.