Skip to content

Commit f92e18e

Browse files
committed
Fix: Exclude read-only properties from KernelJsonSchema generation
1 parent 91f7956 commit f92e18e

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

dotnet/src/InternalUtilities/src/Schema/KernelJsonSchemaBuilder.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ private static JsonSerializerOptions GetDefaultOptions()
6767
{
6868
JsonSerializerOptions options = new()
6969
{
70-
TypeInfoResolver = new DefaultJsonTypeInfoResolver(),
70+
TypeInfoResolver = new DefaultJsonTypeInfoResolver
71+
{
72+
Modifiers = { ExcludeReadOnlyProperties }
73+
},
7174
Converters = { new JsonStringEnumConverter() },
7275
};
7376
options.MakeReadOnly();
@@ -76,4 +79,19 @@ private static JsonSerializerOptions GetDefaultOptions()
7679

7780
return s_options;
7881
}
82+
83+
private static void ExcludeReadOnlyProperties(JsonTypeInfo typeInfo)
84+
{
85+
if (typeInfo.Kind != JsonTypeInfoKind.Object) return;
86+
87+
for (int i = 0; i < typeInfo.Properties.Count; i++)
88+
{
89+
var property = typeInfo.Properties[i];
90+
91+
if (property.Set == null)
92+
{
93+
typeInfo.Properties.RemoveAt(i--);
94+
}
95+
}
96+
}
7997
}

dotnet/src/SemanticKernel.UnitTests/Functions/KernelJsonSchemaTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft. All rights reserved.
22

33
using System;
4+
using System.ComponentModel;
45
using System.Text;
56
using System.Text.Json;
67
using Microsoft.SemanticKernel;
@@ -91,6 +92,39 @@ public void ItThrowsOnInvalidJson()
9192
Assert.ThrowsAny<JsonException>(() => KernelJsonSchema.Parse(Encoding.UTF8.GetBytes(InvalidJsonSchema)));
9293
}
9394

95+
[Fact]
96+
public void ItShouldExcludeReadOnlyPropertiesFromSchema()
97+
{
98+
var function = KernelFunctionFactory.CreateFromMethod(
99+
(MyComplexType input) => { },
100+
"TestFunction");
101+
102+
var schema = function.Metadata.Parameters[0].Schema;
103+
var jsonSchemaString = schema?.ToString();
104+
105+
Assert.NotNull(jsonSchemaString);
106+
Assert.Contains("Status", jsonSchemaString);
107+
Assert.DoesNotContain("Derived", jsonSchemaString);
108+
}
109+
110+
/// <summary>
111+
/// A helper class specific to this test case.
112+
/// Used to verify that read-only properties are ignored by the schema generator.
113+
/// </summary>
114+
private class MyComplexType
115+
{
116+
[Description("The current status of the user account")]
117+
public MyStatus Status { get; set; }
118+
119+
public string Derived => $"Status is {Status}";
120+
}
121+
122+
private enum MyStatus
123+
{
124+
Active,
125+
Inactive
126+
}
127+
94128
// TODO: KernelJsonSchema currently validates that the input is valid JSON but not that it's valid JSON schema.
95129
//[Theory]
96130
//[InlineData("{ \"type\":\"invalid\" }")]

0 commit comments

Comments
 (0)