Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,5 @@ public sealed record class AIJsonSchemaCreateOptions
/// <summary>
/// Gets a value indicating whether to mark all properties as required in the schema.
/// </summary>
public bool RequireAllProperties { get; init; } = true;
public bool RequireAllProperties { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,7 @@ private ChatCompletionsOptions ToAzureAIOptions(IEnumerable<ChatMessage> chatCon
["required"] = BinaryData.FromBytes(JsonSerializer.SerializeToUtf8Bytes(tool.Required, JsonContext.Default.ListString)),
["additionalProperties"] = _falseString,
},
json.SchemaDescription,
jsonSchemaIsStrict: true);
json.SchemaDescription);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -611,8 +611,7 @@ private static ChatCompletionOptions ToOpenAIOptions(ChatOptions? options)
jsonFormat.SchemaName ?? "json_schema",
BinaryData.FromBytes(
JsonSerializer.SerializeToUtf8Bytes(jsonSchema, ChatClientJsonContext.Default.JsonElement)),
jsonFormat.SchemaDescription,
jsonSchemaIsStrict: true) :
jsonFormat.SchemaDescription) :
OpenAI.Chat.ChatResponseFormat.CreateJsonObjectFormat();
}
}
Expand All @@ -623,11 +622,10 @@ private static ChatCompletionOptions ToOpenAIOptions(ChatOptions? options)
/// <summary>Converts an Extensions function to an OpenAI chat tool.</summary>
private static ChatTool ToOpenAIChatTool(AIFunction aiFunction)
{
// Default strict to true, but allow to be overridden by an additional Strict property.
bool strict =
!aiFunction.AdditionalProperties.TryGetValue("Strict", out object? strictObj) ||
strictObj is not bool strictValue ||
strictValue;
bool? strict =
aiFunction.AdditionalProperties.TryGetValue("strictJsonSchema", out object? strictObj) &&
strictObj is bool strictValue ?
strictValue : null;

// Map to an intermediate model so that redundant properties are skipped.
var tool = JsonSerializer.Deserialize(aiFunction.JsonSchema, ChatClientJsonContext.Default.ChatToolJson)!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -418,8 +418,7 @@ private static ResponseCreationOptions ToOpenAIResponseCreationOptions(ChatOptio
ResponseTextFormat.CreateJsonSchemaFormat(
jsonFormat.SchemaName ?? "json_schema",
BinaryData.FromBytes(JsonSerializer.SerializeToUtf8Bytes(jsonSchema, ResponseClientJsonContext.Default.JsonElement)),
jsonFormat.SchemaDescription,
jsonSchemaIsStrict: true) :
jsonFormat.SchemaDescription) :
ResponseTextFormat.CreateJsonObjectFormat(),
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ public static class ChatClientStructuredOutputExtensions
{
IncludeSchemaKeyword = true,
DisallowAdditionalProperties = true,
IncludeTypeInEnumSchemas = true
IncludeTypeInEnumSchemas = true,
RequireAllProperties = true,
};

/// <summary>Sends chat messages, requesting a response matching the type <typeparamref name="T"/>.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public static void AIJsonSchemaCreateOptions_DefaultInstance_ReturnsExpectedValu
Assert.True(options.IncludeTypeInEnumSchemas);
Assert.True(options.DisallowAdditionalProperties);
Assert.False(options.IncludeSchemaKeyword);
Assert.True(options.RequireAllProperties);
Assert.False(options.RequireAllProperties);
Assert.Null(options.TransformSchemaNode);
}

Expand Down Expand Up @@ -148,11 +148,11 @@ public static void CreateJsonSchema_DefaultParameters_GeneratesExpectedJsonSchem
"enum": ["A", "B"]
},
"Value": {
"description": "Default value: \"defaultValue\"",
"type": ["string", "null"]
"type": ["string", "null"],
"default": "defaultValue"
}
},
"required": ["Key", "EnumValue", "Value"],
"required": ["Key", "EnumValue"],
"additionalProperties": false
}
""").RootElement;
Expand All @@ -168,7 +168,7 @@ public static void CreateJsonSchema_OverriddenParameters_GeneratesExpectedJsonSc
JsonElement expected = JsonDocument.Parse("""
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "alternative description",
"description": "alternative description (Default value: null)",
"type": "object",
"properties": {
"Key": {
Expand All @@ -179,12 +179,11 @@ public static void CreateJsonSchema_OverriddenParameters_GeneratesExpectedJsonSc
"enum": ["A", "B"]
},
"Value": {
"type": ["string", "null"],
"default": "defaultValue"
"description": "Default value: \"defaultValue\"",
"type": ["string", "null"]
}
},
"required": ["Key", "EnumValue"],
"default": null
"required": ["Key", "EnumValue", "Value"]
}
""").RootElement;

Expand All @@ -193,7 +192,7 @@ public static void CreateJsonSchema_OverriddenParameters_GeneratesExpectedJsonSc
IncludeTypeInEnumSchemas = false,
DisallowAdditionalProperties = false,
IncludeSchemaKeyword = true,
RequireAllProperties = false,
RequireAllProperties = true,
};

JsonElement actual = AIJsonUtilities.CreateJsonSchema(
Expand Down Expand Up @@ -224,11 +223,11 @@ public static void CreateJsonSchema_UserDefinedTransformer()
"enum": ["A", "B"]
},
"Value": {
"description": "Default value: \"defaultValue\"",
"type": ["string", "null"]
"type": ["string", "null"],
"default": "defaultValue"
}
},
"required": ["Key", "EnumValue", "Value"],
"required": ["Key", "EnumValue"],
"additionalProperties": false
}
""").RootElement;
Expand Down Expand Up @@ -270,7 +269,6 @@ public static void CreateJsonSchema_FiltersDisallowedKeywords()
"type": "string"
}
},
"required": ["Date","TimeSpan","Char"],
"additionalProperties": false
}
""").RootElement;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,8 +385,7 @@ public async Task ResponseFormat_JsonSchema_NonStreaming()
"required":["description"],
"additionalProperties":false
},
"description":"An object with a description",
"strict":true
"description":"An object with a description"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,6 @@ public async Task FunctionCallContent_NonStreaming()
"function": {
"description": "Gets the age of the specified person.",
"name": "GetPersonAge",
"strict":true,
"parameters": {
"type": "object",
"required": [
Expand Down Expand Up @@ -868,7 +867,6 @@ public async Task FunctionCallContent_Streaming()
"function": {
"description": "Gets the age of the specified person.",
"name": "GetPersonAge",
"strict":true,
"parameters": {
"type": "object",
"required": [
Expand Down
Loading