@@ -16,6 +16,21 @@ import ArgumentParser
16
16
import Foundation
17
17
import GoogleGenerativeAI
18
18
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
+
19
34
@main
20
35
struct GenerateContent : AsyncParsableCommand {
21
36
@Option ( help: " The API key to use when calling the Generative Language API. " )
@@ -54,8 +69,47 @@ struct GenerateContent: AsyncParsableCommand {
54
69
}
55
70
56
71
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
+
57
107
do {
58
- let model = GenerativeModel ( name: modelNameOrDefault ( ) , apiKey: apiKey)
108
+ let model = GenerativeModel (
109
+ name: modelNameOrDefault ( ) ,
110
+ apiKey: apiKey,
111
+ generationConfig: generationConfig
112
+ )
59
113
60
114
var parts = [ ModelContent . Part] ( )
61
115
@@ -79,19 +133,32 @@ struct GenerateContent: AsyncParsableCommand {
79
133
80
134
let input = [ ModelContent ( parts: parts) ]
81
135
136
+ var generatedText = " "
82
137
if isStreaming {
83
138
let contentStream = model. generateContentStream ( input)
84
139
print ( " Generated Content <streaming>: " )
85
140
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. " )
88
143
}
144
+ generatedText += text
89
145
}
90
146
} else {
91
147
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. " )
94
150
}
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)
95
162
}
96
163
} catch {
97
164
print ( " Generate Content Error: \( error) " )
0 commit comments