Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion FirebaseVertexAI/Sources/GenerationConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@ public struct GenerationConfig {
/// - `application/json`: JSON response in the candidates.
public let responseMIMEType: String?

/// Output schema of the generated candidate text.
/// If set, a compatible ``responseMIMEType`` must also be set.
///
/// Compatible MIME types:
/// - `application/json`: Schema for JSON response.
///
/// Refer to the [Control generated
/// output](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/control-generated-output)
/// guide for more details.
public let responseSchema: Schema?

/// Creates a new `GenerationConfig` value.
///
/// - Parameter temperature: See ``temperature``
Expand All @@ -78,9 +89,12 @@ public struct GenerationConfig {
/// - Parameter candidateCount: See ``candidateCount``
/// - Parameter maxOutputTokens: See ``maxOutputTokens``
/// - Parameter stopSequences: See ``stopSequences``
/// - Parameter responseMIMEType: See ``responseMIMEType``
/// - Parameter responseSchema: See ``responseSchema``
public init(temperature: Float? = nil, topP: Float? = nil, topK: Int? = nil,
candidateCount: Int? = nil, maxOutputTokens: Int? = nil,
stopSequences: [String]? = nil, responseMIMEType: String? = nil) {
stopSequences: [String]? = nil, responseMIMEType: String? = nil,
responseSchema: Schema? = nil) {
// Explicit init because otherwise if we re-arrange the above variables it changes the API
// surface.
self.temperature = temperature
Expand All @@ -90,6 +104,7 @@ public struct GenerationConfig {
self.maxOutputTokens = maxOutputTokens
self.stopSequences = stopSequences
self.responseMIMEType = responseMIMEType
self.responseSchema = responseSchema
}
}

Expand Down
49 changes: 43 additions & 6 deletions FirebaseVertexAI/Tests/Unit/GenerationConfigTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,16 @@ final class GenerationConfigTests: XCTestCase {
let candidateCount = 2
let maxOutputTokens = 256
let stopSequences = ["END", "DONE"]
let responseMIMEType = "text/plain"
let responseMIMEType = "application/json"
let generationConfig = GenerationConfig(
temperature: temperature,
topP: topP,
topK: topK,
candidateCount: candidateCount,
maxOutputTokens: maxOutputTokens,
stopSequences: stopSequences,
responseMIMEType: responseMIMEType
responseMIMEType: responseMIMEType,
responseSchema: Schema(type: .array, items: Schema(type: .string))
)

let jsonData = try encoder.encode(generationConfig)
Expand All @@ -67,6 +68,12 @@ final class GenerationConfigTests: XCTestCase {
"candidateCount" : \(candidateCount),
"maxOutputTokens" : \(maxOutputTokens),
"responseMIMEType" : "\(responseMIMEType)",
"responseSchema" : {
"items" : {
"type" : "STRING"
},
"type" : "ARRAY"
},
"stopSequences" : [
"END",
"DONE"
Expand All @@ -78,16 +85,46 @@ final class GenerationConfigTests: XCTestCase {
""")
}

func testEncodeGenerationConfig_responseMIMEType() throws {
let mimeType = "image/jpeg"
let generationConfig = GenerationConfig(responseMIMEType: mimeType)
func testEncodeGenerationConfig_jsonResponse() throws {
let mimeType = "application/json"
let generationConfig = GenerationConfig(
responseMIMEType: mimeType,
responseSchema: Schema(
type: .object,
properties: [
"firstName": Schema(type: .string),
"lastName": Schema(type: .string),
"age": Schema(type: .integer),
],
requiredProperties: ["firstName", "lastName", "age"]
)
)

let jsonData = try encoder.encode(generationConfig)

let json = try XCTUnwrap(String(data: jsonData, encoding: .utf8))
XCTAssertEqual(json, """
{
"responseMIMEType" : "\(mimeType)"
"responseMIMEType" : "\(mimeType)",
"responseSchema" : {
"properties" : {
"age" : {
"type" : "INTEGER"
},
"firstName" : {
"type" : "STRING"
},
"lastName" : {
"type" : "STRING"
}
},
"required" : [
"firstName",
"lastName",
"age"
],
"type" : "OBJECT"
}
}
""")
}
Expand Down