@@ -60,10 +60,11 @@ public final class Schema: Sendable {
6060 let rawValue : String
6161 }
6262
63- let dataType : DataType
63+ // May only be nil for `anyOf` schemas, which do not have an explicit `type` in the OpenAPI spec.
64+ let dataType : DataType ?
6465
6566 /// The data type.
66- public var type : String { dataType. rawValue }
67+ public var type : String { dataType? . rawValue ?? " UNSPECIFIED " }
6768
6869 /// The format of the data.
6970 public let format : String ?
@@ -106,6 +107,16 @@ public final class Schema: Sendable {
106107 /// property's type and constraints.
107108 public let properties : [ String : Schema ] ?
108109
110+ /// An array of `Schema` objects. The generated data must be valid against *any* (one or more)
111+ /// of the schemas listed in this array. This allows specifying multiple possible structures or
112+ /// types for a single field.
113+ ///
114+ /// For example, a value could be either a `String` or an `Integer`:
115+ /// ```
116+ /// Schema.anyOf(schemas: [.string(), .integer()])
117+ /// ```
118+ public let anyOf : [ Schema ] ?
119+
109120 /// An array of strings, where each string is the name of a property defined in the `properties`
110121 /// dictionary that must be present in the generated object. If a property is listed here, the
111122 /// model must include it in the output.
@@ -119,12 +130,14 @@ public final class Schema: Sendable {
119130 /// serialization.
120131 public let propertyOrdering : [ String ] ?
121132
122- required init ( type: DataType , format: String ? = nil , description: String ? = nil ,
123- title: String ? = nil ,
124- nullable: Bool = false , enumValues: [ String ] ? = nil , items: Schema ? = nil ,
125- minItems: Int ? = nil , maxItems: Int ? = nil , minimum: Double ? = nil ,
126- maximum: Double ? = nil , properties: [ String : Schema ] ? = nil ,
127- requiredProperties: [ String ] ? = nil , propertyOrdering: [ String ] ? = nil ) {
133+ required init ( type: DataType ? , format: String ? = nil , description: String ? = nil ,
134+ title: String ? = nil , nullable: Bool ? = nil , enumValues: [ String ] ? = nil ,
135+ items: Schema ? = nil , minItems: Int ? = nil , maxItems: Int ? = nil ,
136+ minimum: Double ? = nil , maximum: Double ? = nil , anyOf: [ Schema ] ? = nil ,
137+ properties: [ String : Schema ] ? = nil , requiredProperties: [ String ] ? = nil ,
138+ propertyOrdering: [ String ] ? = nil ) {
139+ precondition ( type != nil || anyOf != nil ,
140+ " A schema must have either a `type` or an `anyOf` array of sub-schemas. " )
128141 dataType = type
129142 self . format = format
130143 self . description = description
@@ -136,6 +149,7 @@ public final class Schema: Sendable {
136149 self . maxItems = maxItems
137150 self . minimum = minimum
138151 self . maximum = maximum
152+ self . anyOf = anyOf
139153 self . properties = properties
140154 self . requiredProperties = requiredProperties
141155 self . propertyOrdering = propertyOrdering
@@ -278,6 +292,10 @@ public final class Schema: Sendable {
278292 /// - format: An optional modifier describing the expected format of the integer. Currently the
279293 /// formats ``IntegerFormat/int32`` and ``IntegerFormat/int64`` are supported; custom values
280294 /// may be specified using ``IntegerFormat/custom(_:)`` but may be ignored by the model.
295+ /// - minimum: If specified, instructs the model that the value should be greater than or
296+ /// equal to the specified minimum.
297+ /// - maximum: If specified, instructs the model that the value should be less than or equal
298+ /// to the specified maximum.
281299 public static func integer( description: String ? = nil , nullable: Bool = false ,
282300 format: IntegerFormat ? = nil ,
283301 minimum: Int ? = nil , maximum: Int ? = nil ) -> Schema {
@@ -362,8 +380,11 @@ public final class Schema: Sendable {
362380 /// - optionalProperties: A list of property names that may be be omitted in objects generated
363381 /// by the model; these names must correspond to the keys provided in the `properties`
364382 /// dictionary and may be an empty list.
383+ /// - propertyOrdering: An optional hint to the model suggesting the order for keys in the
384+ /// generated JSON string. See ``propertyOrdering`` for details.
365385 /// - description: An optional description of what the object should contain or represent; may
366386 /// use Markdown format.
387+ /// - title: An optional human-readable name/summary for the object schema.
367388 /// - nullable: If `true`, instructs the model that it may return `null` instead of an object;
368389 /// defaults to `false`, enforcing that an object is returned.
369390 public static func object( properties: [ String : Schema ] , optionalProperties: [ String ] = [ ] ,
@@ -388,6 +409,38 @@ public final class Schema: Sendable {
388409 propertyOrdering: propertyOrdering
389410 )
390411 }
412+
413+ /// Returns a `Schema` representing a value that must conform to *any* (one or more) of the
414+ /// provided sub-schemas.
415+ ///
416+ /// This schema instructs the model to produce data that is valid against at least one of the
417+ /// schemas listed in the `schemas` array. This is useful when a field can accept multiple
418+ /// distinct types or structures.
419+ ///
420+ /// **Example:** A field that can hold either a simple user ID (integer) or a detailed user
421+ /// object.
422+ /// ```
423+ /// Schema.anyOf(schemas: [
424+ /// .integer(description: "User ID"),
425+ /// .object(properties: [
426+ /// "userId": .integer(),
427+ /// "userName": .string()
428+ /// ], description: "Detailed User Object")
429+ /// ])
430+ /// ```
431+ /// The generated data could be decoded based on which schema it matches.
432+ ///
433+ /// - Parameters:
434+ /// - schemas: An array of `Schema` objects. The generated data must be valid against at least
435+ /// one of these schemas. The array must not be empty.
436+ public static func anyOf( schemas: [ Schema ] ) -> Schema {
437+ if schemas. isEmpty {
438+ VertexLog . error ( code: . invalidSchemaFormat, " The `anyOf` schemas array cannot be empty. " )
439+ }
440+ // Note: The 'type' for an 'anyOf' schema is implicitly defined by the presence of the
441+ // 'anyOf' keyword and doesn't have a specific explicit type like "OBJECT" or "STRING".
442+ return self . init ( type: nil , anyOf: schemas)
443+ }
391444}
392445
393446// MARK: - Codable Conformance
@@ -406,6 +459,7 @@ extension Schema: Encodable {
406459 case maxItems
407460 case minimum
408461 case maximum
462+ case anyOf
409463 case properties
410464 case requiredProperties = " required "
411465 case propertyOrdering
0 commit comments