mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-10 22:45:59 +05:45
110 lines
4.2 KiB
Swift
110 lines
4.2 KiB
Swift
// Copyright 2024 Google LLC
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
import FirebaseAILogic
|
|
import FirebaseCore
|
|
import XCTest
|
|
|
|
// These snippet tests are intentionally skipped in CI jobs; see the README file in this directory
|
|
// for instructions on running them manually.
|
|
|
|
final class FunctionCallingSnippets: XCTestCase {
|
|
override func setUpWithError() throws {
|
|
try FirebaseApp.configureDefaultAppForSnippets()
|
|
}
|
|
|
|
override func tearDown() async throws {
|
|
await FirebaseApp.deleteDefaultAppForSnippets()
|
|
}
|
|
|
|
func testFunctionCalling() async throws {
|
|
// This function calls a hypothetical external API that returns
|
|
// a collection of weather information for a given location on a given date.
|
|
func fetchWeather(city: String, state: String, date: String) -> JSONObject {
|
|
// TODO(developer): Write a standard function that would call an external weather API.
|
|
|
|
// For demo purposes, this hypothetical response is hardcoded here in the expected format.
|
|
return [
|
|
"temperature": .number(38),
|
|
"chancePrecipitation": .string("56%"),
|
|
"cloudConditions": .string("partlyCloudy"),
|
|
]
|
|
}
|
|
|
|
let fetchWeatherTool = FunctionDeclaration(
|
|
name: "fetchWeather",
|
|
description: "Get the weather conditions for a specific city on a specific date.",
|
|
parameters: [
|
|
"location": .object(
|
|
properties: [
|
|
"city": .string(description: "The city of the location."),
|
|
"state": .string(description: "The US state of the location."),
|
|
],
|
|
description: """
|
|
The name of the city and its state for which to get the weather. Only cities in the
|
|
USA are supported.
|
|
"""
|
|
),
|
|
"date": .string(
|
|
description: """
|
|
The date for which to get the weather. Date must be in the format: YYYY-MM-DD.
|
|
"""
|
|
),
|
|
]
|
|
)
|
|
|
|
// Initialize the Vertex AI service and the generative model.
|
|
// Use a model that supports function calling, like a Gemini 1.5 model.
|
|
let model = FirebaseAI.firebaseAI().generativeModel(
|
|
modelName: "gemini-2.0-flash",
|
|
// Provide the function declaration to the model.
|
|
tools: [.functionDeclarations([fetchWeatherTool])]
|
|
)
|
|
|
|
let chat = model.startChat()
|
|
let 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 response = try await chat.sendMessage(prompt)
|
|
|
|
var functionResponses = [FunctionResponsePart]()
|
|
|
|
// When the model responds with one or more function calls, invoke the function(s).
|
|
for functionCall in response.functionCalls {
|
|
if functionCall.name == "fetchWeather" {
|
|
// TODO(developer): Handle invalid arguments.
|
|
guard case let .object(location) = functionCall.args["location"] else { fatalError() }
|
|
guard case let .string(city) = location["city"] else { fatalError() }
|
|
guard case let .string(state) = location["state"] else { fatalError() }
|
|
guard case let .string(date) = functionCall.args["date"] else { fatalError() }
|
|
|
|
functionResponses.append(FunctionResponsePart(
|
|
name: functionCall.name,
|
|
response: fetchWeather(city: city, state: state, date: date)
|
|
))
|
|
}
|
|
// TODO(developer): Handle other potential function calls, if any.
|
|
}
|
|
|
|
// Send the response(s) from the function back to the model so that the model can use it
|
|
// to generate its final response.
|
|
let finalResponse = try await chat.sendMessage(
|
|
[ModelContent(role: "user", parts: functionResponses)]
|
|
)
|
|
|
|
// Log the text response.
|
|
print(finalResponse.text ?? "No text in response.")
|
|
}
|
|
}
|