@@ -49,6 +49,7 @@ public enum SchemaType {
4949 SchemaType . Boolean => "BOOLEAN" ,
5050 SchemaType . Array => "ARRAY" ,
5151 SchemaType . Object => "OBJECT" ,
52+ null => null ,
5253 _ => throw new ArgumentOutOfRangeException ( nameof ( Type ) , Type , "Invalid SchemaType value" )
5354 } ;
5455
@@ -73,12 +74,20 @@ public static StringFormat Custom(string format) {
7374 /// <summary>
7475 /// The data type.
7576 /// </summary>
76- public SchemaType Type { get ; }
77+ public SchemaType ? Type { get ; }
7778 /// <summary>
78- /// A brief description of the parameter.
79+ /// A human-readable explanation of the purpose of the schema or property. While not strictly
80+ /// enforced on the value itself, good descriptions significantly help the model understand the
81+ /// context and generate more relevant and accurate output.
7982 /// </summary>
8083 public string Description { get ; }
8184 /// <summary>
85+ /// A human-readable name/summary for the schema or a specific property. This helps document the
86+ /// schema's purpose but doesn't typically constrain the generated value. It can subtly guide the
87+ /// model by clarifying the intent of a field.
88+ /// </summary>
89+ public string Title { get ; }
90+ /// <summary>
8291 /// Indicates if the value may be null.
8392 /// </summary>
8493 public bool ? Nullable { get ; }
@@ -96,40 +105,90 @@ public static StringFormat Custom(string format) {
96105 /// Schema of the elements of type "Array".
97106 /// </summary>
98107 public Schema Items { get ; }
108+ /// <summary>
109+ /// An integer specifying the minimum number of items the generated "Array" must contain.
110+ /// </summary>
111+ public int ? MinItems { get ; }
112+ /// <summary>
113+ /// An integer specifying the maximum number of items the generated "Array" must contain.
114+ /// </summary>
115+ public int ? MaxItems { get ; }
116+
117+ /// <summary>
118+ /// The minimum value of a numeric type.
119+ /// </summary>
120+ public double ? Minimum { get ; }
121+ /// <summary>
122+ /// The maximum value of a numeric type.
123+ /// </summary>
124+ public double ? Maximum { get ; }
99125
100126 /// <summary>
101127 /// Properties of type "Object".
102128 /// </summary>
103129 public IReadOnlyDictionary < string , Schema > Properties { get ; }
130+
104131 private readonly ReadOnlyCollection < string > _requiredProperties ;
105132 /// <summary>
106133 /// Required properties of type "Object".
107134 /// </summary>
108135 public IEnumerable < string > RequiredProperties => _requiredProperties ;
109136
137+ private readonly ReadOnlyCollection < string > _propertyOrdering ;
138+ /// <summary>
139+ /// A specific hint provided to the Gemini model, suggesting the order in which the keys should
140+ /// appear in the generated JSON string. Important: Standard JSON objects are inherently unordered
141+ /// collections of key-value pairs. While the model will try to respect PropertyOrdering in its
142+ /// textual JSON output, subsequent parsing into native C# objects (like Dictionaries) might
143+ /// not preserve this order. This parameter primarily affects the raw JSON string
144+ /// serialization.
145+ /// </summary>
146+ public IEnumerable < string > PropertyOrdering => _propertyOrdering ;
147+
148+ private readonly ReadOnlyCollection < Schema > _anyOf ;
149+ /// <summary>
150+ /// An array of `Schema` objects. The generated data must be valid against *any* (one or more)
151+ /// of the schemas listed in this array. This allows specifying multiple possible structures or
152+ /// types for a single field.
153+ ///
154+ /// For example, a value could be either a `String` or an `Int`:
155+ /// ```
156+ /// Schema.AnyOf(new [] { Schema.String(), Schema.Int() })
157+ /// ```
158+ /// </summary>
159+ public IEnumerable < Schema > AnyOfSchemas => _anyOf ;
160+
110161 private Schema (
111- SchemaType type ,
162+ SchemaType ? type ,
112163 string description = null ,
164+ string title = null ,
113165 bool ? nullable = null ,
114166 string format = null ,
115167 IEnumerable < string > enumValues = null ,
116168 Schema items = null ,
169+ int ? minItems = null ,
170+ int ? maxItems = null ,
171+ double ? minimum = null ,
172+ double ? maximum = null ,
117173 IDictionary < string , Schema > properties = null ,
118- IEnumerable < string > requiredProperties = null ) {
174+ IEnumerable < string > requiredProperties = null ,
175+ IEnumerable < string > propertyOrdering = null ,
176+ IEnumerable < Schema > anyOf = null ) {
119177 Type = type ;
120178 Description = description ;
179+ Title = title ;
121180 Nullable = nullable ;
122181 Format = format ;
123- _enumValues = new ReadOnlyCollection < string > (
124- enumValues ? . ToList ( ) ?? new List < string > ( ) ) ;
182+ _enumValues = enumValues ? . ToList ( ) . AsReadOnly ( ) ;
125183 Items = items ;
126- if ( properties == null ) {
127- Properties = new Dictionary < string , Schema > ( ) ;
128- } else {
129- Properties = new Dictionary < string , Schema > ( properties ) ;
130- }
131- _requiredProperties = new ReadOnlyCollection < string > (
132- requiredProperties ? . ToList ( ) ?? new List < string > ( ) ) ;
184+ MinItems = minItems ;
185+ MaxItems = maxItems ;
186+ Minimum = minimum ;
187+ Maximum = maximum ;
188+ Properties = ( properties == null ) ? null : new Dictionary < string , Schema > ( properties ) ;
189+ _requiredProperties = requiredProperties ? . ToList ( ) . AsReadOnly ( ) ;
190+ _propertyOrdering = propertyOrdering ? . ToList ( ) . AsReadOnly ( ) ;
191+ _anyOf = anyOf ? . ToList ( ) . AsReadOnly ( ) ;
133192 }
134193
135194 /// <summary>
@@ -155,13 +214,21 @@ public static Schema Boolean(
155214 /// </summary>
156215 /// <param name="description">An optional description of what the integer should contain or represent.</param>
157216 /// <param name="nullable">Indicates whether the value can be `null`. Defaults to `false`.</param>
217+ /// <param name="minimum">If specified, instructs the model that the value should be greater than or
218+ /// equal to the specified minimum.</param>
219+ /// <param name="maximum">If specified, instructs the model that the value should be less than or
220+ /// equal to the specified maximum.</param>
158221 public static Schema Int (
159222 string description = null ,
160- bool nullable = false ) {
223+ bool nullable = false ,
224+ int ? minimum = null ,
225+ int ? maximum = null ) {
161226 return new Schema ( SchemaType . Integer ,
162227 description : description ,
163228 nullable : nullable ,
164- format : "int32"
229+ format : "int32" ,
230+ minimum : minimum ,
231+ maximum : maximum
165232 ) ;
166233 }
167234
@@ -170,12 +237,20 @@ public static Schema Int(
170237 /// </summary>
171238 /// <param name="description">An optional description of what the number should contain or represent.</param>
172239 /// <param name="nullable">Indicates whether the value can be `null`. Defaults to `false`.</param>
240+ /// <param name="minimum">If specified, instructs the model that the value should be greater than or
241+ /// equal to the specified minimum.</param>
242+ /// <param name="maximum">If specified, instructs the model that the value should be less than or
243+ /// equal to the specified maximum.</param>
173244 public static Schema Long (
174245 string description = null ,
175- bool nullable = false ) {
246+ bool nullable = false ,
247+ long ? minimum = null ,
248+ long ? maximum = null ) {
176249 return new Schema ( SchemaType . Integer ,
177250 description : description ,
178- nullable : nullable
251+ nullable : nullable ,
252+ minimum : minimum ,
253+ maximum : maximum
179254 ) ;
180255 }
181256
@@ -184,12 +259,20 @@ public static Schema Long(
184259 /// </summary>
185260 /// <param name="description">An optional description of what the number should contain or represent.</param>
186261 /// <param name="nullable">Indicates whether the value can be `null`. Defaults to `false`.</param>
262+ /// <param name="minimum">If specified, instructs the model that the value should be greater than or
263+ /// equal to the specified minimum.</param>
264+ /// <param name="maximum">If specified, instructs the model that the value should be less than or
265+ /// equal to the specified maximum.</param>
187266 public static Schema Double (
188267 string description = null ,
189- bool nullable = false ) {
268+ bool nullable = false ,
269+ double ? minimum = null ,
270+ double ? maximum = null ) {
190271 return new Schema ( SchemaType . Number ,
191272 description : description ,
192- nullable : nullable
273+ nullable : nullable ,
274+ minimum : minimum ,
275+ maximum : maximum
193276 ) ;
194277 }
195278
@@ -202,13 +285,21 @@ public static Schema Double(
202285 /// </summary>
203286 /// <param name="description">An optional description of what the number should contain or represent.</param>
204287 /// <param name="nullable">Indicates whether the value can be `null`. Defaults to `false`.</param>
288+ /// <param name="minimum">If specified, instructs the model that the value should be greater than or
289+ /// equal to the specified minimum.</param>
290+ /// <param name="maximum">If specified, instructs the model that the value should be less than or
291+ /// equal to the specified maximum.</param>
205292 public static Schema Float (
206293 string description = null ,
207- bool nullable = false ) {
294+ bool nullable = false ,
295+ float ? minimum = null ,
296+ float ? maximum = null ) {
208297 return new Schema ( SchemaType . Number ,
209298 description : description ,
210299 nullable : nullable ,
211- format : "float"
300+ format : "float" ,
301+ minimum : minimum ,
302+ maximum : maximum
212303 ) ;
213304 }
214305
@@ -247,12 +338,17 @@ public static Schema String(
247338 /// <param name="optionalProperties">The list of optional properties. They must correspond to the keys
248339 /// provided in the `properties` map. By default it's empty, signaling the model that all
249340 /// properties are to be included.</param>
341+ /// <param name="propertyOrdering">An optional hint to the model suggesting the order for keys in the
342+ /// generated JSON string.</param>
250343 /// <param name="description">An optional description of what the object represents.</param>
344+ /// <param name="title">An optional human-readable name/summary for the object schema.</param>
251345 /// <param name="nullable">Indicates whether the value can be `null`. Defaults to `false`.</param>
252346 public static Schema Object (
253347 IDictionary < string , Schema > properties ,
254348 IEnumerable < string > optionalProperties = null ,
349+ IEnumerable < string > propertyOrdering = null ,
255350 string description = null ,
351+ string title = null ,
256352 bool nullable = false ) {
257353 if ( properties == null ) {
258354 throw new ArgumentNullException ( nameof ( properties ) ) ;
@@ -281,9 +377,11 @@ public static Schema Object(
281377
282378 return new Schema ( SchemaType . Object ,
283379 description : description ,
380+ title : title ,
284381 nullable : nullable ,
285382 properties : properties ,
286- requiredProperties : required
383+ requiredProperties : required ,
384+ propertyOrdering : propertyOrdering
287385 ) ;
288386 }
289387
@@ -293,19 +391,27 @@ public static Schema Object(
293391 /// <param name="items">The `Schema` of the elements stored in the array.</param>
294392 /// <param name="description">An optional description of what the array represents.</param>
295393 /// <param name="nullable">Indicates whether the value can be `null`. Defaults to `false`.</param>
394+ /// <param name="minItems">Instructs the model to produce at least the specified minimum number of elements
395+ /// in the array.</param>
396+ /// <param name="maxItems">Instructs the model to produce at most the specified minimum number of elements
397+ /// in the array.</param>
296398 public static Schema Array (
297399 Schema items ,
298400 string description = null ,
299- bool nullable = false ) {
401+ bool nullable = false ,
402+ int ? minItems = null ,
403+ int ? maxItems = null ) {
300404 return new Schema ( SchemaType . Array ,
301405 description : description ,
302406 nullable : nullable ,
303- items : items
407+ items : items ,
408+ minItems : minItems ,
409+ maxItems : maxItems
304410 ) ;
305411 }
306412
307413 /// <summary>
308- /// Returns a [ Schema] for an enumeration.
414+ /// Returns a ` Schema` for an enumeration.
309415 ///
310416 /// For example, the cardinal directions can be represented as:
311417 /// ```
@@ -327,6 +433,28 @@ public static Schema Enum(
327433 ) ;
328434 }
329435
436+ /// <summary>
437+ /// Returns a `Schema` representing a value that must conform to *any* (one or more) of the
438+ /// provided sub-schemas.
439+ ///
440+ /// This schema instructs the model to produce data that is valid against at least one of the
441+ /// schemas listed in the `schemas` array. This is useful when a field can accept multiple
442+ /// distinct types or structures.
443+ /// </summary>
444+ /// <param name="schemas">An array of `Schema` objects. The generated data must be valid against at least
445+ /// one of these schemas. The array must not be empty.</param>
446+ public static Schema AnyOf (
447+ IEnumerable < Schema > schemas ) {
448+ if ( schemas == null || ! schemas . Any ( ) ) {
449+ throw new ArgumentException ( "The `AnyOf` schemas array cannot be empty." ) ;
450+ }
451+
452+ // The backend doesn't define a SchemaType for AnyOf, instead using the existence of 'anyOf'.
453+ return new Schema ( null ,
454+ anyOf : schemas
455+ ) ;
456+ }
457+
330458 /// <summary>
331459 /// Intended for internal use only.
332460 /// This method is used for serializing the object to JSON for the API request.
@@ -338,6 +466,9 @@ internal Dictionary<string, object> ToJson() {
338466 if ( ! string . IsNullOrWhiteSpace ( Description ) ) {
339467 json [ "description" ] = Description ;
340468 }
469+ if ( ! string . IsNullOrWhiteSpace ( Title ) ) {
470+ json [ "title" ] = Title ;
471+ }
341472 if ( Nullable . HasValue ) {
342473 json [ "nullable" ] = Nullable . Value ;
343474 }
@@ -347,6 +478,18 @@ internal Dictionary<string, object> ToJson() {
347478 if ( Items != null ) {
348479 json [ "items" ] = Items . ToJson ( ) ;
349480 }
481+ if ( MinItems != null ) {
482+ json [ "minItems" ] = MinItems . Value ;
483+ }
484+ if ( MaxItems != null ) {
485+ json [ "maxItems" ] = MaxItems . Value ;
486+ }
487+ if ( Minimum != null ) {
488+ json [ "minimum" ] = Minimum . Value ;
489+ }
490+ if ( Maximum != null ) {
491+ json [ "maximum" ] = Maximum . Value ;
492+ }
350493 if ( Properties != null && Properties . Any ( ) ) {
351494 Dictionary < string , object > propertiesJson = new ( ) ;
352495 foreach ( var kvp in Properties ) {
@@ -358,6 +501,12 @@ internal Dictionary<string, object> ToJson() {
358501 if ( RequiredProperties != null && RequiredProperties . Any ( ) ) {
359502 json [ "required" ] = RequiredProperties . ToList ( ) ;
360503 }
504+ if ( PropertyOrdering != null && PropertyOrdering . Any ( ) ) {
505+ json [ "propertyOrdering" ] = PropertyOrdering . ToList ( ) ;
506+ }
507+ if ( AnyOfSchemas != null && AnyOfSchemas . Any ( ) ) {
508+ json [ "anyOf" ] = AnyOfSchemas . Select ( s => s . ToJson ( ) ) . ToList ( ) ;
509+ }
361510
362511 return json ;
363512 }
0 commit comments