Skip to content

Commit 88582e6

Browse files
committed
Adding kernel return metadata init ctor
1 parent 2fa7c33 commit 88582e6

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

dotnet/src/SemanticKernel.Abstractions/Functions/KernelReturnParameterMetadata.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,23 @@ public KernelReturnParameterMetadata(JsonSerializerOptions jsonSerializerOptions
4545
this._jsonSerializerOptions = jsonSerializerOptions;
4646
}
4747

48+
/// <summary>Initializes the <see cref="KernelReturnParameterMetadata"/> with all properties.</summary>
49+
/// <param name="description">The description of the return parameter.</param>
50+
/// <param name="parameterType">The .NET type of the return parameter.</param>
51+
/// <param name="schema">The JSON schema describing the return parameter's type.</param>
52+
/// <param name="jsonSerializerOptions">The <see cref="JsonSerializerOptions"/> to generate JSON schema.</param>
53+
public KernelReturnParameterMetadata(
54+
string? description = null,
55+
Type? parameterType = null,
56+
KernelJsonSchema? schema = null,
57+
JsonSerializerOptions? jsonSerializerOptions = null)
58+
: this(jsonSerializerOptions ?? null!)
59+
{
60+
this.Description = description;
61+
this.ParameterType = parameterType;
62+
this.Schema = schema;
63+
}
64+
4865
/// <summary>Initializes a <see cref="KernelReturnParameterMetadata"/> as a copy of another <see cref="KernelReturnParameterMetadata"/>.</summary>
4966
[RequiresUnreferencedCode("Uses reflection, if no JSOs are available in the metadata, to generate the schema, making it incompatible with AOT scenarios.")]
5067
[RequiresDynamicCode("Uses reflection, if no JSOs are available in the metadata, to generate the schema, making it incompatible with AOT scenarios.")]

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

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,128 @@ public void ItRepresentsUnderlyingType()
9797
Assert.Equal(typeof(string), KernelFunctionFactory.CreateFromMethod(async () => "42").Metadata.ReturnParameter.ParameterType);
9898
Assert.Equal(typeof(string), KernelFunctionFactory.CreateFromMethod(async ValueTask<string> () => "42").Metadata.ReturnParameter.ParameterType);
9999
}
100+
101+
[Fact]
102+
public void ItCanBeConstructedWithAllParameters()
103+
{
104+
// Test the new constructor that accepts all parameters
105+
var schema = KernelJsonSchema.Parse("""{ "type": "string", "description": "test return schema" }""");
106+
var m = new KernelReturnParameterMetadata(
107+
description: "Return parameter description",
108+
parameterType: typeof(string),
109+
schema: schema);
110+
111+
Assert.Equal("Return parameter description", m.Description);
112+
Assert.Equal(typeof(string), m.ParameterType);
113+
Assert.Equal(JsonSerializer.Serialize(schema), JsonSerializer.Serialize(m.Schema));
114+
}
115+
116+
[Fact]
117+
public void ItCanBeConstructedWithAllParametersAndJsonSerializerOptions()
118+
{
119+
// Test the new constructor with JsonSerializerOptions
120+
var jsos = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
121+
var schema = KernelJsonSchema.Parse("""{ "type": "integer" }""");
122+
var m = new KernelReturnParameterMetadata(
123+
description: "Return parameter",
124+
parameterType: typeof(int),
125+
schema: schema,
126+
jsonSerializerOptions: jsos);
127+
128+
Assert.Equal("Return parameter", m.Description);
129+
Assert.Equal(typeof(int), m.ParameterType);
130+
Assert.Equal(JsonSerializer.Serialize(schema), JsonSerializer.Serialize(m.Schema));
131+
}
132+
133+
[Fact]
134+
public void ItUsesDefaultValuesInNewConstructor()
135+
{
136+
// Test that optional parameters have correct default values
137+
var m = new KernelReturnParameterMetadata();
138+
139+
Assert.Empty(m.Description);
140+
Assert.Null(m.ParameterType);
141+
Assert.Null(m.Schema);
142+
}
143+
144+
[Fact]
145+
public void ItInfersSchemaWhenNotProvidedInNewConstructor()
146+
{
147+
// Test that schema is inferred from type when not explicitly provided
148+
var m = new KernelReturnParameterMetadata(
149+
description: "An integer return parameter",
150+
parameterType: typeof(int));
151+
152+
Assert.NotNull(m.Schema);
153+
Assert.Equal(JsonSerializer.Serialize(KernelJsonSchema.Parse("""{"description":"An integer return parameter", "type":"integer"}""")), JsonSerializer.Serialize(m.Schema));
154+
}
155+
156+
[Fact]
157+
public void ItHandlesNullDescriptionInNewConstructor()
158+
{
159+
// Test that null description is handled correctly
160+
var m = new KernelReturnParameterMetadata(
161+
description: null,
162+
parameterType: typeof(string));
163+
164+
Assert.Empty(m.Description); // null description should become empty string
165+
Assert.Equal(typeof(string), m.ParameterType);
166+
}
167+
168+
[Fact]
169+
public void ItHandlesNullSchemaInNewConstructor()
170+
{
171+
// Test that null schema parameter is handled correctly
172+
var m = new KernelReturnParameterMetadata(
173+
description: "Test return param",
174+
parameterType: typeof(string),
175+
schema: null);
176+
177+
Assert.Equal("Test return param", m.Description);
178+
Assert.Equal(typeof(string), m.ParameterType);
179+
// Schema should be inferred from type since explicit schema is null
180+
Assert.NotNull(m.Schema);
181+
}
182+
183+
[Theory]
184+
[ClassData(typeof(TestJsonSerializerOptionsForPrimitives))]
185+
public void ItUsesJsonSerializerOptionsInNewConstructor(JsonSerializerOptions? jsos)
186+
{
187+
// Test that JsonSerializerOptions are used correctly in the new constructor
188+
var m = jsos is not null ?
189+
new KernelReturnParameterMetadata(
190+
description: "Test return parameter",
191+
parameterType: typeof(int),
192+
jsonSerializerOptions: jsos) :
193+
new KernelReturnParameterMetadata(
194+
description: "Test return parameter",
195+
parameterType: typeof(int));
196+
197+
Assert.Equal("Test return parameter", m.Description);
198+
Assert.Equal(typeof(int), m.ParameterType);
199+
Assert.Equal(JsonSerializer.Serialize(KernelJsonSchema.Parse("""{"description":"Test return parameter", "type":"integer"}""")), JsonSerializer.Serialize(m.Schema));
200+
}
201+
202+
[Fact]
203+
public void ItHandlesOnlyDescriptionInNewConstructor()
204+
{
205+
// Test constructor with only description parameter
206+
var m = new KernelReturnParameterMetadata(description: "Only description provided");
207+
208+
Assert.Equal("Only description provided", m.Description);
209+
Assert.Null(m.ParameterType);
210+
Assert.Null(m.Schema);
211+
}
212+
213+
[Fact]
214+
public void ItHandlesOnlyParameterTypeInNewConstructor()
215+
{
216+
// Test constructor with only parameter type
217+
var m = new KernelReturnParameterMetadata(parameterType: typeof(bool));
218+
219+
Assert.Empty(m.Description);
220+
Assert.Equal(typeof(bool), m.ParameterType);
221+
Assert.NotNull(m.Schema);
222+
Assert.Equal(JsonSerializer.Serialize(KernelJsonSchema.Parse("""{"type":"boolean"}""")), JsonSerializer.Serialize(m.Schema));
223+
}
100224
}

0 commit comments

Comments
 (0)