|
| 1 | +package com.google.firebase.quickstart.ai.feature.text |
| 2 | + |
| 3 | +import com.google.firebase.Firebase |
| 4 | +import com.google.firebase.ai.Chat |
| 5 | +import com.google.firebase.ai.ai |
| 6 | +import com.google.firebase.ai.type.AutoFunctionDeclaration |
| 7 | +import com.google.firebase.ai.type.Content |
| 8 | +import com.google.firebase.ai.type.FirebaseAutoFunctionException |
| 9 | +import com.google.firebase.ai.type.FunctionResponsePart |
| 10 | +import com.google.firebase.ai.type.GenerativeBackend |
| 11 | +import com.google.firebase.ai.type.JsonSchema |
| 12 | +import com.google.firebase.ai.type.Tool |
| 13 | +import com.google.firebase.quickstart.ai.feature.text.functioncalling.WeatherRepository |
| 14 | +import com.google.firebase.quickstart.ai.ui.UiChatMessage |
| 15 | +import kotlinx.serialization.Serializable |
| 16 | +import kotlinx.serialization.json.JsonObject |
| 17 | +import kotlinx.serialization.json.jsonPrimitive |
| 18 | + |
| 19 | +@Serializable |
| 20 | +object AutoFunctionCallRoute |
| 21 | + |
| 22 | +class AutoFunctionCallViewModel : ChatViewModel() { |
| 23 | + |
| 24 | + override val initialPrompt: String = "What was the weather in Boston, MA on October 17, 2024?" |
| 25 | + |
| 26 | + private val chat: Chat |
| 27 | + |
| 28 | + init { |
| 29 | + val generativeModel = Firebase.ai( |
| 30 | + backend = GenerativeBackend.googleAI() |
| 31 | + ).generativeModel( |
| 32 | + modelName = "gemini-3.1-flash-lite", |
| 33 | + tools = listOf( |
| 34 | + Tool.functionDeclarations( |
| 35 | + autoFunctionDeclarations = listOf( |
| 36 | + AutoFunctionDeclaration.create( |
| 37 | + functionName = "fetchWeather", |
| 38 | + description = "Get the weather conditions for a specific US city on a specific date.", |
| 39 | + inputSchema = JsonSchema.obj( |
| 40 | + properties = mapOf( |
| 41 | + "city" to JsonSchema.string("The US city of the location."), |
| 42 | + "state" to JsonSchema.string("The US state of the location."), |
| 43 | + "date" to JsonSchema.string( |
| 44 | + "The date for which to get the weather." + |
| 45 | + " Date must be in the format: YYYY-MM-DD." |
| 46 | + ), |
| 47 | + ) |
| 48 | + ), |
| 49 | + functionReference = ::fetchWeather |
| 50 | + ) |
| 51 | + ) |
| 52 | + ) |
| 53 | + ) |
| 54 | + ) |
| 55 | + chat = generativeModel.startChat() |
| 56 | + } |
| 57 | + |
| 58 | + override suspend fun performSendMessage(prompt: Content, currentMessages: List<UiChatMessage>) { |
| 59 | + val response = chat.sendMessage(prompt) |
| 60 | + validateAndDisplayResponse(response, currentMessages) |
| 61 | + } |
| 62 | + |
| 63 | + private suspend fun fetchWeather(input: JsonObject): FunctionResponsePart { |
| 64 | + val city = input["city"]?.jsonPrimitive?.content |
| 65 | + val state = input["state"]?.jsonPrimitive?.content |
| 66 | + val date = input["date"]?.jsonPrimitive?.content |
| 67 | + |
| 68 | + return if (city == null || state == null || date == null) { |
| 69 | + // Tell the model there was an error |
| 70 | + throw FirebaseAutoFunctionException("Unable to fetch weather - one of the parameters was null") |
| 71 | + } else { |
| 72 | + // Execute the function call and return the response |
| 73 | + val functionResponse = WeatherRepository |
| 74 | + .fetchWeather(city, state, date) |
| 75 | + |
| 76 | + FunctionResponsePart("fetchWeather", functionResponse) |
| 77 | + } |
| 78 | + } |
| 79 | +} |
| 80 | + |
0 commit comments