// Copyright 2025 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 Foundation /// A type that represents a remote multimodal model (like Gemini), with the ability to generate /// content based on various input types. /// /// **Public Preview**: This API is a public preview and may be subject to change. @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *) public final class TemplateGenerativeModel: Sendable { let generativeAIService: GenerativeAIService let apiConfig: APIConfig init(generativeAIService: GenerativeAIService, apiConfig: APIConfig) { self.generativeAIService = generativeAIService self.apiConfig = apiConfig } /// Generates content from a prompt template and inputs. /// /// **Public Preview**: This API is a public preview and may be subject to change. /// /// - Parameters: /// - templateID: The ID of the prompt template to use. /// - inputs: A dictionary of variables to substitute into the template. /// - options: The ``RequestOptions`` for the request, currently used to override default /// request timeout. /// - Returns: The content generated by the model. /// - Throws: A ``GenerateContentError`` if the request failed. public func generateContent(templateID: String, inputs: [String: Any], options: RequestOptions = RequestOptions()) async throws -> GenerateContentResponse { let templateInputs = try inputs.mapValues { try TemplateInput(value: $0) } return try await generateContentWithHistory( history: [], template: templateID, inputs: templateInputs, options: options ) } /// Generates content from a prompt template, inputs, and history. /// /// - Parameters: /// - history: The conversation history to use. /// - template: The prompt template to use. /// - inputs: A dictionary of variables to substitute into the template. /// - Returns: The content generated by the model. /// - Throws: A ``GenerateContentError`` if the request failed. func generateContentWithHistory(history: [ModelContent], template: String, inputs: [String: TemplateInput], options: RequestOptions = RequestOptions()) async throws -> GenerateContentResponse { let request = TemplateGenerateContentRequest( template: template, inputs: inputs, history: history, projectID: generativeAIService.firebaseInfo.projectID, stream: false, apiConfig: apiConfig, options: options ) let response: GenerateContentResponse = try await generativeAIService .loadRequest(request: request) return response } /// Generates content from a prompt template and inputs, with streaming responses. /// /// **Public Preview**: This API is a public preview and may be subject to change. /// /// - Parameters: /// - templateID: The ID of the prompt template to use. /// - inputs: A dictionary of variables to substitute into the template. /// - options: The ``RequestOptions`` for the request, currently used to override default /// request timeout. /// - Returns: An `AsyncThrowingStream` that yields `GenerateContentResponse` objects. /// - Throws: A ``GenerateContentError`` if the request failed. public func generateContentStream(templateID: String, inputs: [String: Any], options: RequestOptions = RequestOptions()) throws -> AsyncThrowingStream { let templateInputs = try inputs.mapValues { try TemplateInput(value: $0) } let request = TemplateGenerateContentRequest( template: templateID, inputs: templateInputs, history: [], projectID: generativeAIService.firebaseInfo.projectID, stream: true, apiConfig: apiConfig, options: options ) return generativeAIService.loadRequestStream(request: request) } func generateContentStreamWithHistory(history: [ModelContent], template: String, inputs: [String: TemplateInput], options: RequestOptions = RequestOptions()) throws -> AsyncThrowingStream { let request = TemplateGenerateContentRequest( template: template, inputs: inputs, history: history, projectID: generativeAIService.firebaseInfo.projectID, stream: true, apiConfig: apiConfig, options: options ) return generativeAIService.loadRequestStream(request: request) } // TODO: Restore `public` determined to be releaseable along with the contents of TemplateChatSession. /// Creates a new chat conversation using this model with the provided history and template. /// /// - Parameters: /// - templateID: The ID of the prompt template to use. /// - history: The conversation history to use. /// - Returns: A new ``TemplateChatSession`` instance. func startChat(templateID: String, history: [ModelContent] = []) -> TemplateChatSession { return TemplateChatSession( model: self, templateID: templateID, history: history ) } }