Skip to content

Commit e3ab034

Browse files
authored
fix: MeaiFunction argumennts Type handling
Added more robust codes to handle argument types
2 parents 2ffaa1e + 9ba450e commit e3ab034

File tree

71 files changed

+92
-4143
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+92
-4143
lines changed

CSharpToJsonSchema.sln

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
21
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 16
4-
VisualStudioVersion = 16.0.30204.135
2+
# Visual Studio Version 17
3+
VisualStudioVersion = 17.12.35506.116 d17.12
54
MinimumVisualStudioVersion = 10.0.40219.1
65
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E793AF18-4371-4EBD-96FC-195EB1798855}"
76
ProjectSection(SolutionItems) = preProject
@@ -25,9 +24,9 @@ EndProject
2524
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{2D8B78DE-7269-417B-9D0B-8981FA513ACB}"
2625
ProjectSection(SolutionItems) = preProject
2726
.github\workflows\auto-merge.yml = .github\workflows\auto-merge.yml
27+
.github\dependabot.yml = .github\dependabot.yml
2828
.github\workflows\dotnet.yml = .github\workflows\dotnet.yml
2929
.github\workflows\pull-request.yml = .github\workflows\pull-request.yml
30-
.github\dependabot.yml = .github\dependabot.yml
3130
EndProjectSection
3231
EndProject
3332
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpToJsonSchema", "src\libs\CSharpToJsonSchema\CSharpToJsonSchema.csproj", "{93367DED-6C55-4267-923A-4412D03376FB}"
@@ -80,10 +79,14 @@ Global
8079
{6167F915-83EB-42F9-929B-AD4719A55811}.Debug|Any CPU.Build.0 = Debug|Any CPU
8180
{6167F915-83EB-42F9-929B-AD4719A55811}.Release|Any CPU.ActiveCfg = Release|Any CPU
8281
{6167F915-83EB-42F9-929B-AD4719A55811}.Release|Any CPU.Build.0 = Release|Any CPU
83-
{1942E3E5-F151-4C90-BECE-140AAD8C66DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
84-
{1942E3E5-F151-4C90-BECE-140AAD8C66DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
8582
{DC07C90E-A58C-44B3-82D2-E2EB8F777B92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
8683
{DC07C90E-A58C-44B3-82D2-E2EB8F777B92}.Debug|Any CPU.Build.0 = Debug|Any CPU
84+
{DC07C90E-A58C-44B3-82D2-E2EB8F777B92}.Release|Any CPU.ActiveCfg = Release|Any CPU
85+
{DC07C90E-A58C-44B3-82D2-E2EB8F777B92}.Release|Any CPU.Build.0 = Release|Any CPU
86+
{1942E3E5-F151-4C90-BECE-140AAD8C66DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
87+
{1942E3E5-F151-4C90-BECE-140AAD8C66DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
88+
{1942E3E5-F151-4C90-BECE-140AAD8C66DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
89+
{1942E3E5-F151-4C90-BECE-140AAD8C66DE}.Release|Any CPU.Build.0 = Release|Any CPU
8790
EndGlobalSection
8891
GlobalSection(SolutionProperties) = preSolution
8992
HideSolutionNode = FALSE

src/libs/CSharpToJsonSchema.Generators/Conversion/ToModels.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ public static InterfaceData PrepareMethodData(
136136

137137
return string.Join(".", commonParts);
138138
}
139+
139140
private static OpenApiSchema ToParameterData(ITypeSymbol typeSymbol, string? name = null,
140141
string? description = null, bool isRequired = true)
141142
{

src/libs/CSharpToJsonSchema.Generators/Sources.Method.MeaiTools.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public partial class {extensionsClassName}
3030
foreach (var tool in tools)
3131
{{
3232
var call = calls[tool.Name];
33-
lst.Add(new global::CSharpToJsonSchema.MeaiFunction(tool, call));
33+
lst.Add(new global::CSharpToJsonSchema.MeaiFunction(tool, call, global::{@interface.Namespace}.{extensionsClassName}JsonSerializerContext.Default.Options));
3434
}}
3535
return lst;
3636
}}
@@ -59,7 +59,7 @@ public partial class {extensionsClassName}
5959
foreach (var tool in tools)
6060
{{
6161
var call = calls[tool.Name];
62-
lst.Add(new global::CSharpToJsonSchema.MeaiFunction(tool, call));
62+
lst.Add(new global::CSharpToJsonSchema.MeaiFunction(tool, call, global::{@interface.Namespace}.{extensionsClassName}JsonSerializerContext.Default.Options));
6363
}}
6464
return lst;
6565
}}

src/libs/CSharpToJsonSchema/MeaiFunction.cs

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System.Collections.ObjectModel;
22
using System.Text.Json;
33
using System.Text.Json.Nodes;
4+
using System.Text.Json.Serialization;
5+
using System.Text.Json.Serialization.Metadata;
46
using Microsoft.Extensions.AI;
57

68
namespace CSharpToJsonSchema;
@@ -29,6 +31,8 @@ public partial class MeaiFunction : AIFunction
2931
/// Gets the description of the tool.
3032
/// </summary>
3133
public override string Description => _tool.Description;
34+
35+
private JsonSerializerOptions? _options;
3236

3337
/// <summary>
3438
/// Gets additional properties associated with the tool.
@@ -40,7 +44,7 @@ public partial class MeaiFunction : AIFunction
4044
/// </summary>
4145
/// <param name="tool">The tool associated with this function.</param>
4246
/// <param name="call">The function to execute the tool with input arguments.</param>
43-
public MeaiFunction(Tool tool, Func<string, CancellationToken, Task<string>> call)
47+
public MeaiFunction(Tool tool, Func<string, CancellationToken, Task<string>> call, JsonSerializerOptions? options = null)
4448
{
4549
this._tool = tool;
4650
this._call = call;
@@ -53,8 +57,31 @@ public MeaiFunction(Tool tool, Func<string, CancellationToken, Task<string>> cal
5357
{
5458
tool.AdditionalProperties.Add("Strict", true);
5559
}
60+
61+
_options = options;
5662
}
5763

64+
65+
66+
private JsonSerializerOptions InitializeReflectionOptions()
67+
{
68+
#pragma warning disable IL2026, IL3050 // Reflection is used only when enabled
69+
if(!JsonSerializer.IsReflectionEnabledByDefault)
70+
throw new InvalidOperationException("JsonSerializer.IsReflectionEnabledByDefault is false, please pass in a JsonSerializerOptions instance.");
71+
72+
_options = new JsonSerializerOptions()
73+
{
74+
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
75+
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
76+
PropertyNameCaseInsensitive = true,
77+
Converters = { new JsonStringEnumConverter() },
78+
TypeInfoResolver = new DefaultJsonTypeInfoResolver()
79+
};
80+
return _options;
81+
#pragma warning restore IL2026, IL3050 // Reflection is used only when enabled
82+
}
83+
84+
5885
/// <summary>
5986
/// Invokes the tool with the given arguments asynchronously.
6087
/// </summary>
@@ -76,7 +103,7 @@ public MeaiFunction(Tool tool, Func<string, CancellationToken, Task<string>> cal
76103
/// </summary>
77104
/// <param name="arguments">The arguments to be converted into a JSON string.</param>
78105
/// <returns>A JSON string representation of the arguments.</returns>
79-
private string GetArgsString(IEnumerable<KeyValuePair<string, object?>> arguments)
106+
protected virtual string GetArgsString(IEnumerable<KeyValuePair<string, object?>> arguments)
80107
{
81108
var jsonObject = new JsonObject();
82109

@@ -93,6 +120,43 @@ private string GetArgsString(IEnumerable<KeyValuePair<string, object?>> argument
93120
}
94121
else if (args.Value is JsonNode node)
95122
{
123+
jsonObject[args.Key] = node;
124+
}
125+
else if (args.Value is JsonValue val)
126+
{
127+
jsonObject[args.Key] = val;
128+
}
129+
else if( args.Value is JsonObject obj)
130+
{
131+
jsonObject[args.Key] = obj;
132+
}
133+
else if (args.Value is JsonArray arr)
134+
{
135+
jsonObject[args.Key] = arr;
136+
}
137+
else
138+
{
139+
var type = args.Value?.GetType();
140+
// if(type.IsPrimitive)
141+
// {
142+
// jsonObject[args.Key] = JsonValue.Create(args.Value);
143+
// }
144+
// else
145+
// {
146+
if (_options == null)
147+
{
148+
#pragma warning disable IL2026, IL3050 // Reflection is used only when enabled
149+
//Fallback to Reflection
150+
//This will break the AOT, Hoping for the best, IChatClient implementation only send JSON classes
151+
//Or Developer is using the code generator
152+
_options = InitializeReflectionOptions();
153+
#pragma warning disable IL2026, IL3050 // Reflection is used only when enabled
154+
}
155+
var typeInfo = _options.GetTypeInfo(type);
156+
157+
var str = JsonSerializer.Serialize(args.Value, typeInfo);
158+
jsonObject[args.Key] = JsonNode.Parse(str);
159+
//}
96160
}
97161
}
98162

src/libs/CSharpToJsonSchema/TypeToSchemaHelpers.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public static OpenApiSchema AsJsonSchema(
5252
JsonSerializerOptions? options = null)
5353
{
5454
type = type ?? throw new ArgumentNullException(nameof(type));
55-
#pragma warning disable IL2026
55+
#pragma warning disable IL2026, IL3050
5656
var node = new JsonSerializerOptions
5757
{
5858
TypeInfoResolver = jsonTypeInfoResolver ?? new DefaultJsonTypeInfoResolver(),
@@ -61,7 +61,7 @@ public static OpenApiSchema AsJsonSchema(
6161
TransformSchemaNode = (context, node) => node,
6262
TreatNullObliviousAsNonNullable = true,
6363
});
64-
#pragma warning restore IL2026
64+
#pragma warning restore IL2026, IL3050
6565
var schema = Create(type, strict);
6666
if (schema.Type == "object")
6767
{

src/tests/CSharpToJsonSchema.MeaiTests/CSharpToJsonSchema.MeaiTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<PrivateAssets>all</PrivateAssets>
1010
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1111
</PackageReference>
12+
<PackageReference Include="Google_GenerativeAI.Microsoft" Version="2.4.1" />
1213
<PackageReference Include="H.Generators.Tests.Extensions" Version="1.24.2" />
1314
<PackageReference Include="H.Resources.Generator" Version="1.8.0">
1415
<PrivateAssets>all</PrivateAssets>

src/tests/CSharpToJsonSchema.MeaiTests/Meai_Tests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.ClientModel;
22
using CSharpToJsonSchema.MeaiTests.Services;
3+
using GenerativeAI.Microsoft;
34
using Microsoft.Extensions.AI;
45
using OpenAI;
56
using OpenAI.Models;
@@ -34,7 +35,6 @@ public async Task ShouldInvokeTheFunctions()
3435
.Be(true);
3536

3637
Console.WriteLine(response.Text);
37-
3838
}
3939

4040
//[TestMethod]
@@ -47,9 +47,10 @@ public async Task ShouldInvokeTheBookService()
4747

4848
var client = new OpenAIClient(new ApiKeyCredential(key));
4949

50-
Microsoft.Extensions.AI.OpenAIChatClient openAiClient = new OpenAIChatClient(client.GetChatClient("gpt-4o-mini"));
50+
//Microsoft.Extensions.AI.OpenAIChatClient openAiClient = new OpenAIChatClient(client.GetChatClient("gpt-4o-mini"));
5151

52-
var chatClient = new Microsoft.Extensions.AI.FunctionInvokingChatClient(openAiClient);
52+
var chatClient = new GenerativeAIChatClient(Environment.GetEnvironmentVariable("GOOGLE_API_KEY",EnvironmentVariableTarget.User));
53+
//var chatClient = new Microsoft.Extensions.AI.FunctionInvokingChatClient(openAiClient);
5354
var chatOptions = new ChatOptions();
5455

5556
var service = new BookStoreService();
@@ -63,6 +64,5 @@ public async Task ShouldInvokeTheBookService()
6364
.Be(true);
6465

6566
Console.WriteLine(response.Text);
66-
6767
}
6868
}

src/tests/CSharpToJsonSchema.SnapshotTests/SnapshotTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ namespace CSharpToJsonSchema.SnapshotTests;
33
[TestClass]
44
public class ToolTests : VerifyBase
55
{
6-
// [TestMethod]
7-
// public Task MethodFunction()
8-
// {
9-
// return this.CheckSourceAsync(H.Resources.MethodFunctionTools_cs.AsString());
10-
// }
6+
[TestMethod]
7+
public Task MethodFunction()
8+
{
9+
return this.CheckSourceAsync(H.Resources.MethodFunctionTools_cs.AsString());
10+
}
1111

1212
[TestMethod]
1313
public Task Weather()

src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.MethodFunction#ToolsJsonSerializerContext.PropertyNames.g.received.cs

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.MethodFunction#ToolsJsonSerializerContext.PropertyNames.g.verified.cs

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)