mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-11 22:55:59 +05:45
187 lines
7.3 KiB
Swift
187 lines
7.3 KiB
Swift
// Copyright 2023 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 FirebaseAI
|
|
import FirebaseCore
|
|
import XCTest
|
|
#if canImport(AppKit)
|
|
import AppKit // For NSImage extensions.
|
|
#elseif canImport(UIKit)
|
|
import UIKit // For UIImage extensions.
|
|
#endif
|
|
|
|
@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
|
|
final class APITests: XCTestCase {
|
|
func codeSamples() async throws {
|
|
let app = FirebaseApp.app()
|
|
let config = GenerationConfig(temperature: 0.2,
|
|
topP: 0.1,
|
|
topK: 16,
|
|
candidateCount: 4,
|
|
maxOutputTokens: 256,
|
|
stopSequences: ["..."],
|
|
responseMIMEType: "text/plain")
|
|
let filters = [SafetySetting(harmCategory: .dangerousContent, threshold: .blockOnlyHigh)]
|
|
let systemInstruction = ModelContent(
|
|
role: "system",
|
|
parts: TextPart("Talk like a pirate.")
|
|
)
|
|
|
|
let requestOptions = RequestOptions()
|
|
let _ = RequestOptions(timeout: 30.0)
|
|
|
|
// Instantiate Firebase AI SDK - Default App
|
|
let firebaseAI = FirebaseAI.firebaseAI()
|
|
let _ = FirebaseAI.firebaseAI(backend: .googleAI())
|
|
let _ = FirebaseAI.firebaseAI(backend: .vertexAI())
|
|
let _ = FirebaseAI.firebaseAI(backend: .vertexAI(location: "my-location"))
|
|
|
|
// Instantiate Firebase AI SDK - Custom App
|
|
let _ = FirebaseAI.firebaseAI(app: app!)
|
|
let _ = FirebaseAI.firebaseAI(app: app!, backend: .googleAI())
|
|
let _ = FirebaseAI.firebaseAI(app: app!, backend: .vertexAI())
|
|
let _ = FirebaseAI.firebaseAI(app: app!, backend: .vertexAI(location: "my-location"))
|
|
|
|
// Permutations without optional arguments.
|
|
|
|
let _ = firebaseAI.generativeModel(modelName: "gemini-2.0-flash")
|
|
|
|
let _ = firebaseAI.generativeModel(
|
|
modelName: "gemini-2.0-flash",
|
|
safetySettings: filters
|
|
)
|
|
|
|
let _ = firebaseAI.generativeModel(
|
|
modelName: "gemini-2.0-flash",
|
|
generationConfig: config
|
|
)
|
|
|
|
let _ = firebaseAI.generativeModel(
|
|
modelName: "gemini-2.0-flash",
|
|
systemInstruction: systemInstruction
|
|
)
|
|
|
|
// All arguments passed.
|
|
let model = firebaseAI.generativeModel(
|
|
modelName: "gemini-2.0-flash",
|
|
generationConfig: config, // Optional
|
|
safetySettings: filters, // Optional
|
|
systemInstruction: systemInstruction, // Optional
|
|
requestOptions: requestOptions // Optional
|
|
)
|
|
|
|
// Full Typed Usage
|
|
let pngData = Data() // ....
|
|
let contents = [ModelContent(
|
|
role: "user",
|
|
parts: [
|
|
TextPart("Is it a cat?"),
|
|
InlineDataPart(data: pngData, mimeType: "image/png"),
|
|
]
|
|
)]
|
|
|
|
do {
|
|
let response = try await model.generateContent(contents)
|
|
print(response.text ?? "Couldn't get text... check status")
|
|
} catch {
|
|
print("Error generating content: \(error)")
|
|
}
|
|
|
|
// Content input combinations.
|
|
let _ = try await model.generateContent("Constant String")
|
|
let str = "String Variable"
|
|
let _ = try await model.generateContent(str)
|
|
let _ = try await model.generateContent([str])
|
|
let _ = try await model.generateContent(str, "abc", "def")
|
|
let _ = try await model.generateContent(
|
|
str,
|
|
FileDataPart(uri: "gs://test-bucket/image.jpg", mimeType: "image/jpeg")
|
|
)
|
|
#if canImport(UIKit)
|
|
_ = try await model.generateContent(UIImage())
|
|
_ = try await model.generateContent([UIImage()])
|
|
_ = try await model.generateContent([str, UIImage(), TextPart(str)])
|
|
_ = try await model.generateContent(str, UIImage(), "def", UIImage())
|
|
_ = try await model.generateContent([str, UIImage(), "def", UIImage()])
|
|
_ = try await model.generateContent([ModelContent(parts: "def", UIImage()),
|
|
ModelContent(parts: "def", UIImage())])
|
|
#elseif canImport(AppKit)
|
|
_ = try await model.generateContent(NSImage())
|
|
_ = try await model.generateContent([NSImage()])
|
|
_ = try await model.generateContent(str, NSImage(), "def", NSImage())
|
|
_ = try await model.generateContent([str, NSImage(), "def", NSImage()])
|
|
#endif
|
|
|
|
// PartsRepresentable combinations.
|
|
let _ = ModelContent(parts: [TextPart(str)])
|
|
let _ = ModelContent(role: "model", parts: [TextPart(str)])
|
|
let _ = ModelContent(parts: "Constant String")
|
|
let _ = ModelContent(parts: str)
|
|
let _ = ModelContent(parts: [str])
|
|
let _ = ModelContent(parts: [str, InlineDataPart(data: Data(), mimeType: "foo")])
|
|
#if canImport(UIKit)
|
|
_ = ModelContent(role: "user", parts: UIImage())
|
|
_ = ModelContent(role: "user", parts: [UIImage()])
|
|
_ = ModelContent(parts: [str, UIImage()])
|
|
// Note: without explicitly specifying`: [any PartsRepresentable]` this will fail to compile
|
|
// below with "Cannot convert value of type `[Any]` to expected type `[any Part]`.
|
|
let representable2: [any PartsRepresentable] = [str, UIImage()]
|
|
_ = ModelContent(parts: representable2)
|
|
_ = ModelContent(parts: [str, UIImage(), TextPart(str)])
|
|
#elseif canImport(AppKit)
|
|
_ = ModelContent(role: "user", parts: NSImage())
|
|
_ = ModelContent(role: "user", parts: [NSImage()])
|
|
_ = ModelContent(parts: [str, NSImage()])
|
|
// Note: without explicitly specifying`: [any PartsRepresentable]` this will fail to compile
|
|
// below with "Cannot convert value of type `[Any]` to expected type `[any Part]`.
|
|
let representable2: [any PartsRepresentable] = [str, NSImage()]
|
|
_ = ModelContent(parts: representable2)
|
|
_ = ModelContent(parts: [str, NSImage(), TextPart(str)])
|
|
#endif
|
|
|
|
// countTokens API
|
|
let _: CountTokensResponse = try await model.countTokens("What color is the Sky?")
|
|
#if canImport(UIKit)
|
|
let _: CountTokensResponse = try await model.countTokens("What color is the Sky?",
|
|
UIImage())
|
|
let _: CountTokensResponse = try await model.countTokens([
|
|
ModelContent(parts: "What color is the Sky?", UIImage()),
|
|
ModelContent(parts: UIImage(), "What color is the Sky?", UIImage()),
|
|
])
|
|
#endif
|
|
|
|
// Chat
|
|
_ = model.startChat()
|
|
_ = model.startChat(history: [ModelContent(parts: "abc")])
|
|
}
|
|
|
|
// Public API tests for GenerateContentResponse.
|
|
func generateContentResponseAPI() {
|
|
let response = GenerateContentResponse(candidates: [])
|
|
|
|
let _: [Candidate] = response.candidates
|
|
let _: PromptFeedback? = response.promptFeedback
|
|
|
|
// Usage Metadata
|
|
guard let usageMetadata = response.usageMetadata else { fatalError() }
|
|
let _: Int = usageMetadata.promptTokenCount
|
|
let _: Int = usageMetadata.candidatesTokenCount
|
|
let _: Int = usageMetadata.totalTokenCount
|
|
|
|
// Computed Properties
|
|
let _: String? = response.text
|
|
let _: [FunctionCallPart] = response.functionCalls
|
|
}
|
|
}
|