Skip to content

Commit 71d8e92

Browse files
authored
[Vertex AI] Add responseSchema to GenerationConfig (#13576)
1 parent a6fd721 commit 71d8e92

File tree

3 files changed

+63
-7
lines changed

3 files changed

+63
-7
lines changed

FirebaseVertexAI/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
- [changed] **Breaking Change**: The source image in the
1010
`ImageConversionError.couldNotConvertToJPEG` error case is now an enum value
1111
instead of the `Any` type. (#13575)
12+
- [added] Added support for specifying a JSON `responseSchema` in
13+
`GenerationConfig`; see
14+
[control generated output](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/control-generated-output)
15+
for more details. (#13576)
1216

1317
# 10.29.0
1418
- [feature] Added community support for watchOS. (#13215)

FirebaseVertexAI/Sources/GenerationConfig.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,17 @@ public struct GenerationConfig {
7070
/// - `application/json`: JSON response in the candidates.
7171
public let responseMIMEType: String?
7272

73+
/// Output schema of the generated candidate text.
74+
/// If set, a compatible ``responseMIMEType`` must also be set.
75+
///
76+
/// Compatible MIME types:
77+
/// - `application/json`: Schema for JSON response.
78+
///
79+
/// Refer to the [Control generated
80+
/// output](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/control-generated-output)
81+
/// guide for more details.
82+
public let responseSchema: Schema?
83+
7384
/// Creates a new `GenerationConfig` value.
7485
///
7586
/// - Parameter temperature: See ``temperature``
@@ -78,9 +89,12 @@ public struct GenerationConfig {
7889
/// - Parameter candidateCount: See ``candidateCount``
7990
/// - Parameter maxOutputTokens: See ``maxOutputTokens``
8091
/// - Parameter stopSequences: See ``stopSequences``
92+
/// - Parameter responseMIMEType: See ``responseMIMEType``
93+
/// - Parameter responseSchema: See ``responseSchema``
8194
public init(temperature: Float? = nil, topP: Float? = nil, topK: Int? = nil,
8295
candidateCount: Int? = nil, maxOutputTokens: Int? = nil,
83-
stopSequences: [String]? = nil, responseMIMEType: String? = nil) {
96+
stopSequences: [String]? = nil, responseMIMEType: String? = nil,
97+
responseSchema: Schema? = nil) {
8498
// Explicit init because otherwise if we re-arrange the above variables it changes the API
8599
// surface.
86100
self.temperature = temperature
@@ -90,6 +104,7 @@ public struct GenerationConfig {
90104
self.maxOutputTokens = maxOutputTokens
91105
self.stopSequences = stopSequences
92106
self.responseMIMEType = responseMIMEType
107+
self.responseSchema = responseSchema
93108
}
94109
}
95110

FirebaseVertexAI/Tests/Unit/GenerationConfigTests.swift

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,16 @@ final class GenerationConfigTests: XCTestCase {
4848
let candidateCount = 2
4949
let maxOutputTokens = 256
5050
let stopSequences = ["END", "DONE"]
51-
let responseMIMEType = "text/plain"
51+
let responseMIMEType = "application/json"
5252
let generationConfig = GenerationConfig(
5353
temperature: temperature,
5454
topP: topP,
5555
topK: topK,
5656
candidateCount: candidateCount,
5757
maxOutputTokens: maxOutputTokens,
5858
stopSequences: stopSequences,
59-
responseMIMEType: responseMIMEType
59+
responseMIMEType: responseMIMEType,
60+
responseSchema: Schema(type: .array, items: Schema(type: .string))
6061
)
6162

6263
let jsonData = try encoder.encode(generationConfig)
@@ -67,6 +68,12 @@ final class GenerationConfigTests: XCTestCase {
6768
"candidateCount" : \(candidateCount),
6869
"maxOutputTokens" : \(maxOutputTokens),
6970
"responseMIMEType" : "\(responseMIMEType)",
71+
"responseSchema" : {
72+
"items" : {
73+
"type" : "STRING"
74+
},
75+
"type" : "ARRAY"
76+
},
7077
"stopSequences" : [
7178
"END",
7279
"DONE"
@@ -78,16 +85,46 @@ final class GenerationConfigTests: XCTestCase {
7885
""")
7986
}
8087

81-
func testEncodeGenerationConfig_responseMIMEType() throws {
82-
let mimeType = "image/jpeg"
83-
let generationConfig = GenerationConfig(responseMIMEType: mimeType)
88+
func testEncodeGenerationConfig_jsonResponse() throws {
89+
let mimeType = "application/json"
90+
let generationConfig = GenerationConfig(
91+
responseMIMEType: mimeType,
92+
responseSchema: Schema(
93+
type: .object,
94+
properties: [
95+
"firstName": Schema(type: .string),
96+
"lastName": Schema(type: .string),
97+
"age": Schema(type: .integer),
98+
],
99+
requiredProperties: ["firstName", "lastName", "age"]
100+
)
101+
)
84102

85103
let jsonData = try encoder.encode(generationConfig)
86104

87105
let json = try XCTUnwrap(String(data: jsonData, encoding: .utf8))
88106
XCTAssertEqual(json, """
89107
{
90-
"responseMIMEType" : "\(mimeType)"
108+
"responseMIMEType" : "\(mimeType)",
109+
"responseSchema" : {
110+
"properties" : {
111+
"age" : {
112+
"type" : "INTEGER"
113+
},
114+
"firstName" : {
115+
"type" : "STRING"
116+
},
117+
"lastName" : {
118+
"type" : "STRING"
119+
}
120+
},
121+
"required" : [
122+
"firstName",
123+
"lastName",
124+
"age"
125+
],
126+
"type" : "OBJECT"
127+
}
91128
}
92129
""")
93130
}

0 commit comments

Comments
 (0)