diff --git a/OpenAI.SDK/ObjectModels/Converters.cs b/OpenAI.SDK/ObjectModels/Converters.cs index 549a7050..cd9b2b36 100644 --- a/OpenAI.SDK/ObjectModels/Converters.cs +++ b/OpenAI.SDK/ObjectModels/Converters.cs @@ -89,4 +89,51 @@ public override void Write(Utf8JsonWriter writer, AssistantsApiToolChoiceOneOfTy writer.WriteNullValue(); } } -} \ No newline at end of file +} + +public class SingleOrArrayToListConverter : JsonConverter> +{ + public override IList? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { + switch (reader.TokenType) { + case JsonTokenType.String: + return [reader.GetString()]; + case JsonTokenType.StartArray: + { + var list = new List(); + while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) { + switch (reader.TokenType) { + case JsonTokenType.String: + list.Add(reader.GetString()); + break; + case JsonTokenType.Null: + list.Add(null); + break; + default: + throw new JsonException($"Unexpected token in type array: {reader.TokenType}"); + } + } + return list; + } + default: + throw new JsonException($"Unexpected token parsing type: {reader.TokenType}"); + } + } + + public override void Write(Utf8JsonWriter writer, IList? value, JsonSerializerOptions options) { + if (value == null || value.Count == 0) { + writer.WriteNullValue(); + } else if (value.Count == 1) { + writer.WriteStringValue(value[0]); + } else { + writer.WriteStartArray(); + foreach (var item in value) { + if (item == null) { + writer.WriteNullValue(); + } else { + writer.WriteStringValue(item); + } + } + writer.WriteEndArray(); + } + } +} diff --git a/OpenAI.SDK/ObjectModels/SharedModels/FunctionParameters.cs b/OpenAI.SDK/ObjectModels/SharedModels/FunctionParameters.cs index 743af244..b86fd8e2 100644 --- a/OpenAI.SDK/ObjectModels/SharedModels/FunctionParameters.cs +++ b/OpenAI.SDK/ObjectModels/SharedModels/FunctionParameters.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Betalgo.Ranul.OpenAI.ObjectModels.SharedModels; @@ -20,10 +20,33 @@ public enum FunctionObjectTypes } /// - /// Required. Function parameter object type. Default value is "object". + /// Property's type as a string. Only one: or should be set. + /// + [JsonIgnore] + public string? Type { + get => TypeList?.Count != 1 ? null : TypeList[0]; + set { + if (value == null) { + TypeList = null; + return; + } + TypeList = [value]; + } + } + + /// + /// Property's type as a list of strings. Only one: or should be set. /// [JsonPropertyName("type")] - public string Type { get; set; } = "object"; + [JsonConverter(typeof(SingleOrArrayToListConverter))] + public IList? TypeList { get; set; } + + /// + /// An instance validates successfully against this keyword if its value is equal to the value of the keyword + /// https://json-schema.org/draft/2020-12/json-schema-validation#name-const + /// + [JsonPropertyName("const")] + public string? Constant { get; set; } /// /// Optional. List of "function arguments", as a dictionary that maps from argument name @@ -45,7 +68,15 @@ public enum FunctionObjectTypes public bool? AdditionalProperties { get; set; } /// - /// Optional. Argument description. + /// Optional. Title of the schema. + /// https://json-schema.org/draft/2020-12/json-schema-validation#name-title-and-description + /// + [JsonPropertyName("title")] + public string? Title { get; set; } + + /// + /// Optional. Description of the schema. + /// https://json-schema.org/draft/2020-12/json-schema-validation#name-title-and-description /// [JsonPropertyName("description")] public string? Description { get; set; } @@ -69,6 +100,74 @@ public enum FunctionObjectTypes /// [JsonPropertyName("maxProperties")] public int? MaxProperties { get; set; } + + /// + /// The value of "multipleOf" MUST be a number, strictly greater than 0. + /// A numeric instance is valid only if division by this keyword's value results in an integer. + /// https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.6.2.1 + /// + [JsonPropertyName("multipleOf")] + public float? MultipleOf { get; set; } + + /// + /// The value of "minimum" MUST be a number, representing an inclusive lower limit for a numeric instance. + /// https://json-schema.org/draft/2020-12/json-schema-validation#name-minimum + /// + [JsonPropertyName("minimum")] + public float? Minimum { get; set; } + + /// + /// The value of "exclusiveMinimum" MUST be a number, representing an exclusive lower limit for a numeric + /// instance. If the instance is a number, then the instance is valid only if it has a value strictly greater + /// than (not equal to) "exclusiveMinimum". + /// https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.6.2.5 + /// + [JsonPropertyName("exclusiveMinimum")] + public float? ExclusiveMinimum { get; set; } + + /// + /// The value of "maximum" MUST be a number, representing an inclusive upper limit for a numeric instance. + /// https://json-schema.org/draft/2020-12/json-schema-validation#name-maximum + /// + [JsonPropertyName("maximum")] + public float? Maximum { get; set; } + + /// + /// The value of "exclusiveMaximum" MUST be a number, representing an exclusive upper limit for a numeric + /// instance. If the instance is a number, then the instance is valid only if it has a value strictly less than + /// (not equal to) "exclusiveMaximum". + /// https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.6.2.3 + /// + [JsonPropertyName("exclusiveMaximum")] + public float? ExclusiveMaximum { get; set; } + + /// + /// Predefined formats for strings. Currently supported: + /// date-time, time, date, duration, email, hostname, ipv4, ipv6, uuid + /// + [JsonPropertyName("format")] + public string? Format { get; set; } + + /// + /// A regular expression that the string must match. + /// https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#pattern + /// + [JsonPropertyName("pattern")] + public string? Pattern { get; set; } + + /// + /// The array must have at least this many items. + /// https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.6.4.2 + /// + [JsonPropertyName("minItems")] + public int? MinItems { get; set; } + + /// + /// The array must have at most this many items. + /// https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.6.4.4 + /// + [JsonPropertyName("maxItems")] + public int? MaxItems { get; set; } /// /// If type is "array", this specifies the element type for all items in the array. @@ -77,6 +176,40 @@ public enum FunctionObjectTypes /// [JsonPropertyName("items")] public PropertyDefinition? Items { get; set; } + + /// + /// Definitions of schemas (2020-12 and newer specifications). + /// For more details, see https://json-schema.org/understanding-json-schema/structuring#defs + /// + [JsonPropertyName("$defs")] + public IDictionary? Defs { get; set; } + + /// + /// Definitions of schemas (draft-07 specification). + /// + [JsonPropertyName("definitions")] + public IDictionary? Definitions { get; set; } + + /// + /// Reference to another schema definition. + /// For more details, see https://json-schema.org/understanding-json-schema/structuring#dollarref + /// + [JsonPropertyName("$ref")] + public string? Ref { get; set; } + + /// + /// To validate against anyOf, the given data must be valid against any (one or more) of the given subschemas. + /// For more details, see https://json-schema.org/understanding-json-schema/reference/combining#anyOf + /// + [JsonPropertyName("anyOf")] + public IList? AnyOf { get; set; } + + /// + /// To validate against oneOf, the given data must be valid against exactly one of the given subschemas. + /// For more details, see https://json-schema.org/understanding-json-schema/reference/combining#oneOf + /// + [JsonPropertyName("oneOf")] + public IList? OneOf { get; set; } public static PropertyDefinition DefineArray(PropertyDefinition? arrayItems = null) { @@ -174,4 +307,4 @@ public static string ConvertTypeToString(FunctionObjectTypes type) _ => throw new ArgumentOutOfRangeException(nameof(type), $"Unknown type: {type}") }; } -} \ No newline at end of file +}