Skip to content

Commit 45eaf37

Browse files
author
Gunpal Jain
committed
fix: MeaiFunction Type handling, added more robust codes.
1 parent 0d1df7a commit 45eaf37

File tree

32 files changed

+86
-1080
lines changed

32 files changed

+86
-1080
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: 62 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,7 +57,28 @@ public MeaiFunction(Tool tool, Func<string, CancellationToken, Task<string>> cal
5357
{
5458
tool.AdditionalProperties.Add("Strict", true);
5559
}
60+
61+
_options = options;
62+
}
63+
64+
65+
#pragma warning disable IL2026, IL3050 // Reflection is used only when enabled
66+
private JsonSerializerOptions InitializeReflectionOptions()
67+
{
68+
if(!JsonSerializer.IsReflectionEnabledByDefault)
69+
throw new InvalidOperationException("JsonSerializer.IsReflectionEnabledByDefault is false, please pass in a JsonSerializerOptions instance.");
70+
71+
_options = new JsonSerializerOptions()
72+
{
73+
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
74+
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
75+
PropertyNameCaseInsensitive = true,
76+
Converters = { new JsonStringEnumConverter() },
77+
TypeInfoResolver = new DefaultJsonTypeInfoResolver()
78+
};
79+
return _options;
5680
}
81+
#pragma warning restore IL2026, IL3050 // Reflection is used only when enabled
5782

5883
/// <summary>
5984
/// Invokes the tool with the given arguments asynchronously.
@@ -76,7 +101,7 @@ public MeaiFunction(Tool tool, Func<string, CancellationToken, Task<string>> cal
76101
/// </summary>
77102
/// <param name="arguments">The arguments to be converted into a JSON string.</param>
78103
/// <returns>A JSON string representation of the arguments.</returns>
79-
private string GetArgsString(IEnumerable<KeyValuePair<string, object?>> arguments)
104+
protected virtual string GetArgsString(IEnumerable<KeyValuePair<string, object?>> arguments)
80105
{
81106
var jsonObject = new JsonObject();
82107

@@ -93,6 +118,41 @@ private string GetArgsString(IEnumerable<KeyValuePair<string, object?>> argument
93118
}
94119
else if (args.Value is JsonNode node)
95120
{
121+
jsonObject[args.Key] = node;
122+
}
123+
else if (args.Value is JsonValue val)
124+
{
125+
jsonObject[args.Key] = val;
126+
}
127+
else if( args.Value is JsonObject obj)
128+
{
129+
jsonObject[args.Key] = obj;
130+
}
131+
else if (args.Value is JsonArray arr)
132+
{
133+
jsonObject[args.Key] = arr;
134+
}
135+
else
136+
{
137+
var type = args.Value?.GetType();
138+
if(type.IsPrimitive)
139+
{
140+
jsonObject[args.Key] = JsonValue.Create(args.Value);
141+
}
142+
else
143+
{
144+
if (_options == null)
145+
{
146+
//Fallback to Reflection
147+
//This will break the AOT, Hoping for the best, IChatClient implementation only send JSON classes
148+
//Or Developer is using the code generator
149+
_options = InitializeReflectionOptions();
150+
}
151+
var typeInfo = _options.GetTypeInfo(type);
152+
153+
var str = JsonSerializer.Serialize(args.Value, typeInfo);
154+
jsonObject[args.Key] = JsonNode.Parse(str);
155+
}
96156
}
97157
}
98158

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.

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

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

0 commit comments

Comments
 (0)