Skip to content

Commit fde2baf

Browse files
authored
[Vertex AI] Refactor StringFormat and IntegerFormat as structs (#13865)
1 parent ae484d3 commit fde2baf

File tree

2 files changed

+49
-48
lines changed

2 files changed

+49
-48
lines changed

FirebaseVertexAI/Sources/Types/Public/Schema.swift

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,41 @@ import Foundation
2020
/// [OpenAPI 3.0 schema object](https://spec.openapis.org/oas/v3.0.3#schema).
2121
public class Schema {
2222
/// Modifiers describing the expected format of a string `Schema`.
23-
public enum StringFormat {
23+
public struct StringFormat: EncodableProtoEnum {
24+
// This enum is currently only used to conform `StringFormat` to `ProtoEnum`, which requires
25+
// `associatedtype Kind: RawRepresentable<String>`.
26+
enum Kind: String {
27+
// Providing a case resolves the error "An enum with no cases cannot declare a raw type".
28+
case unused // TODO: Remove `unused` case when we have at least one specific string format.
29+
}
30+
2431
/// A custom string format.
25-
case custom(String)
32+
public static func custom(_ format: String) -> StringFormat {
33+
return self.init(rawValue: format)
34+
}
35+
36+
let rawValue: String
2637
}
2738

2839
/// Modifiers describing the expected format of an integer `Schema`.
29-
public enum IntegerFormat {
40+
public struct IntegerFormat: EncodableProtoEnum {
41+
enum Kind: String {
42+
case int32
43+
case int64
44+
}
45+
3046
/// A 32-bit signed integer.
31-
case int32
47+
public static let int32 = IntegerFormat(kind: .int32)
48+
3249
/// A 64-bit signed integer.
33-
case int64
50+
public static let int64 = IntegerFormat(kind: .int64)
51+
3452
/// A custom integer format.
35-
case custom(String)
53+
public static func custom(_ format: String) -> IntegerFormat {
54+
return self.init(rawValue: format)
55+
}
56+
57+
let rawValue: String
3658
}
3759

3860
let dataType: DataType
@@ -311,45 +333,3 @@ extension Schema: Encodable {
311333
case requiredProperties = "required"
312334
}
313335
}
314-
315-
// MARK: - RawRepresentable Conformance
316-
317-
extension Schema.IntegerFormat: RawRepresentable {
318-
public init?(rawValue: String) {
319-
switch rawValue {
320-
case "int32":
321-
self = .int32
322-
case "int64":
323-
self = .int64
324-
default:
325-
self = .custom(rawValue)
326-
}
327-
}
328-
329-
public var rawValue: String {
330-
switch self {
331-
case .int32:
332-
return "int32"
333-
case .int64:
334-
return "int64"
335-
case let .custom(format):
336-
return format
337-
}
338-
}
339-
}
340-
341-
extension Schema.StringFormat: RawRepresentable {
342-
public init?(rawValue: String) {
343-
switch rawValue {
344-
default:
345-
self = .custom(rawValue)
346-
}
347-
}
348-
349-
public var rawValue: String {
350-
switch self {
351-
case let .custom(format):
352-
return format
353-
}
354-
}
355-
}

FirebaseVertexAI/Tests/Integration/IntegrationTests.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,25 @@ final class IntegrationTests: XCTestCase {
153153
XCTAssertEqual(response.totalTokens, 24)
154154
XCTAssertEqual(response.totalBillableCharacters, 71)
155155
}
156+
157+
func testCountTokens_jsonSchema() async throws {
158+
model = vertex.generativeModel(
159+
modelName: "gemini-1.5-flash",
160+
generationConfig: GenerationConfig(
161+
responseMIMEType: "application/json",
162+
responseSchema: Schema.object(properties: [
163+
"startDate": .string(format: .custom("date")),
164+
"yearsSince": .integer(format: .custom("int16")),
165+
"hoursSince": .integer(format: .int32),
166+
"minutesSince": .integer(format: .int64),
167+
])
168+
)
169+
)
170+
let prompt = "It is 2050-01-01, how many years, hours and minutes since 2000-01-01?"
171+
172+
let response = try await model.countTokens(prompt)
173+
174+
XCTAssertEqual(response.totalTokens, 34)
175+
XCTAssertEqual(response.totalBillableCharacters, 59)
176+
}
156177
}

0 commit comments

Comments
 (0)