Update to M.E.AI 9.3.0-preview.1.25161.3 (#61)

This commit is contained in:
Stephen Toub 2025-03-12 10:23:13 -04:00 • committed by GitHub
commit fe632617dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 20 additions and 142 deletions

View file

@ -8,11 +8,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.AI" Version="9.1.0-preview.1.25064.3" />
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" Version="9.1.0-preview.1.25064.3" />
<PackageReference Include="Microsoft.Extensions.AI" Version="9.3.0-preview.1.25161.3" />
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" Version="9.3.0-preview.1.25161.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\McpDotNet.Extensions.AI\McpDotNet.Extensions.AI.csproj" />
<ProjectReference Include="..\..\..\..\src\mcpdotnet\mcpdotnet.csproj" />
</ItemGroup>

View file

@ -1,79 +0,0 @@
using McpDotNet.Client;
using McpDotNet.Protocol.Types;
using Microsoft.Extensions.AI;
namespace SimpleToolsConsole;
public class McpAIFunction : AIFunction
{
private readonly Tool _tool;
private readonly IMcpClient _client;
private readonly AIFunctionMetadata _metadata;
public McpAIFunction(Tool tool, IMcpClient client)
{
_tool = tool ?? throw new ArgumentNullException(nameof(tool));
_client = client ?? throw new ArgumentNullException(nameof(client));
_metadata = new AIFunctionMetadata(tool.Name)
{
Description = tool.Description,
Parameters = MapFunctionParameters(tool.InputSchema),
ReturnParameter = new AIFunctionReturnParameterMetadata()
{
ParameterType = typeof(string),
}
};
}
public override string ToString() => _tool.Name;
protected async override Task<object?> InvokeCoreAsync(IEnumerable<KeyValuePair<string, object?>> arguments, CancellationToken cancellationToken)
{
if (arguments is null)
{
throw new ArgumentNullException(nameof(arguments));
}
// Convert arguments to dictionary format expected by mcpdotnet
Dictionary<string, object> argDict = [];
foreach (var arg in arguments)
{
if (arg.Value is not null)
{
argDict[arg.Key] = arg.Value;
}
}
// Call the tool through mcpdotnet
var result = await _client.CallToolAsync(
_tool.Name,
argDict.Count == 0 ? [] : argDict,
cancellationToken: cancellationToken
);
// Extract the text content from the result
// For simplicity in this sample, we'll just concatenate all text content
return string.Join("\n", result.Content
.Where(c => c.Type == "text")
.Select(c => c.Text));
}
public override AIFunctionMetadata Metadata => _metadata;
private static List<AIFunctionParameterMetadata> MapFunctionParameters(JsonSchema? jsonSchema)
{
var properties = jsonSchema?.Properties;
if (properties == null)
{
return [];
}
HashSet<string> requiredProperties = [.. jsonSchema!.Required ?? []];
return properties.Select(kvp =>
new AIFunctionParameterMetadata(kvp.Key)
{
Description = kvp.Value.Description,
ParameterType = McpTypeMapper.MapJsonToDotNetType(kvp.Value.Type, requiredProperties.Contains(kvp.Key)),
IsRequired = requiredProperties.Contains(kvp.Key)
}).ToList();
}
}

View file

@ -1,11 +0,0 @@
using McpDotNet.Client;
using McpDotNet.Protocol.Types;
using Microsoft.Extensions.AI;
namespace SimpleToolsConsole;
public static class McpToolExtensions
{
public static AITool ToAITool(this Tool tool, IMcpClient client)
=> new McpAIFunction(tool, client);
}

View file

@ -1,31 +0,0 @@
// Enable nullable reference types, as we need this for dynamic mapping of JSON schema to .NET types
#nullable enable
namespace SimpleToolsConsole;
public static class McpTypeMapper
{
public static Type MapJsonToDotNetType(string jsonType, bool required)
{
// For simplicity, we don't handle complex types in this sample, but use object instead
var baseType = jsonType switch
{
"string" => typeof(string),
"integer" => typeof(int),
"number" => typeof(double),
"boolean" => typeof(bool),
"array" => typeof(IEnumerable<object>),
"object" => typeof(IDictionary<string, object>),
_ => typeof(object)
};
// If it's a value type and not required, make it nullable
if (!required && baseType.IsValueType)
{
return typeof(Nullable<>).MakeGenericType(baseType);
}
// Reference types are already nullable when not required
return baseType;
}
}

View file

@ -1,10 +1,10 @@
using McpDotNet.Client;
using McpDotNet.Configuration;
using McpDotNet.Extensions.AI;
using McpDotNet.Protocol.Transport;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Logging.Abstractions;
using OpenAI;
using SimpleToolsConsole;
internal class Program
{
@ -81,7 +81,7 @@ internal class Program
// Call the chat client
Console.WriteLine("Asking GPT-4o-mini to call the Echo Tool...");
var response = chatClient.CompleteStreamingAsync(
var response = chatClient.GetStreamingResponseAsync(
messages,
new() { Tools = mappedTools });