Skip to content

Commit 309b186

Browse files
committed
Add a schema in the CLI tool for manual testing
1 parent 639123b commit 309b186

File tree

1 file changed

+72
-5
lines changed

1 file changed

+72
-5
lines changed

Examples/GenerativeAICLI/Sources/GenerateContent.swift

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@ import ArgumentParser
1616
import Foundation
1717
import GoogleGenerativeAI
1818

19+
// TODO(andrewheard): Revert the changes in this file after manual testing.
20+
21+
struct CartoonCharacter: Decodable {
22+
let firstName: String
23+
let lastName: String
24+
let occupation: String
25+
let children: [ChildCartoonCharacter]
26+
let birthYear: Int
27+
}
28+
29+
struct ChildCartoonCharacter: Decodable {
30+
let firstName: String
31+
let lastName: String
32+
}
33+
1934
@main
2035
struct GenerateContent: AsyncParsableCommand {
2136
@Option(help: "The API key to use when calling the Generative Language API.")
@@ -54,8 +69,47 @@ struct GenerateContent: AsyncParsableCommand {
5469
}
5570

5671
mutating func run() async throws {
72+
let responseSchema = Schema(
73+
type: .array,
74+
description: "List of characters.",
75+
items: Schema(
76+
type: .object,
77+
description: "Details about a character.",
78+
properties: [
79+
"firstName": Schema(type: .string, description: "The character's first name."),
80+
"lastName": Schema(type: .string, description: "The character's last name."),
81+
"occupation": Schema(type: .string, description: "The character's occupation."),
82+
"children": Schema(
83+
type: .array,
84+
description: "A list of the character's children ordered from oldest to youngest.",
85+
items: Schema(
86+
type: .object,
87+
description: "Details about a child character.",
88+
properties: [
89+
"firstName": Schema(type: .string,
90+
description: "The child character's first name."),
91+
"lastName": Schema(type: .string, description: "The child character's last name."),
92+
],
93+
requiredProperties: ["firstName", "lastName"]
94+
)
95+
),
96+
"birthYear": Schema(type: .integer, format: "int32",
97+
description: "The character's birth year."),
98+
],
99+
requiredProperties: ["firstName", "lastName", "occupation", "children", "birthYear"]
100+
)
101+
)
102+
let generationConfig = GenerationConfig(
103+
responseMIMEType: "application/json",
104+
responseSchema: responseSchema
105+
)
106+
57107
do {
58-
let model = GenerativeModel(name: modelNameOrDefault(), apiKey: apiKey)
108+
let model = GenerativeModel(
109+
name: modelNameOrDefault(),
110+
apiKey: apiKey,
111+
generationConfig: generationConfig
112+
)
59113

60114
var parts = [ModelContent.Part]()
61115

@@ -79,19 +133,32 @@ struct GenerateContent: AsyncParsableCommand {
79133

80134
let input = [ModelContent(parts: parts)]
81135

136+
var generatedText = ""
82137
if isStreaming {
83138
let contentStream = model.generateContentStream(input)
84139
print("Generated Content <streaming>:")
85140
for try await content in contentStream {
86-
if let text = content.text {
87-
print(text)
141+
guard let text = content.text else {
142+
fatalError("No text generated.")
88143
}
144+
generatedText += text
89145
}
90146
} else {
91147
let content = try await model.generateContent(input)
92-
if let text = content.text {
93-
print("Generated Content:\n\(text)")
148+
guard let text = content.text else {
149+
fatalError("No text generated.")
94150
}
151+
generatedText += text
152+
}
153+
154+
guard let jsonData = generatedText.data(using: .utf8) else {
155+
fatalError("Generated text is not UTF-8 compatible.")
156+
}
157+
158+
let jsonDecoder = JSONDecoder()
159+
let cartoonCharacters = try jsonDecoder.decode([CartoonCharacter].self, from: jsonData)
160+
for cartoonCharacter in cartoonCharacters {
161+
print(cartoonCharacter)
95162
}
96163
} catch {
97164
print("Generate Content Error: \(error)")

0 commit comments

Comments
 (0)