mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
.NET: Update A2A, MCP, and system package dependencies (#4647)
* .NET: Update A2A, MCP, and system package dependencies Update dependency versions: - A2A/A2A.AspNetCore: 0.3.3-preview → 0.3.4-preview - ModelContextProtocol: 0.8.0-preview.1 → 1.1.0 - Microsoft.Bcl.AsyncInterfaces: 10.0.3 → 10.0.4 - System.Linq.AsyncEnumerable: 10.0.0 → 10.0.4 - Add Microsoft.Bcl.Memory 10.0.4 Remove internal polyfill extensions now provided by A2A SDK 0.3.4: - A2AMetadataExtensions (source + tests) - AdditionalPropertiesDictionaryExtensions (source + tests) Update DefaultMcpToolHandler to match MCP SDK 1.1.0 API changes where ImageContentBlock.Data and AudioContentBlock.Data changed from string to ReadOnlyMemory<byte>. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * address pr review comments --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Copilot
parent
921c5f9c17
commit
bcb55b4a98
@@ -1,36 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
namespace A2A;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for A2A metadata dictionary.
|
||||
/// </summary>
|
||||
internal static class A2AMetadataExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a dictionary of metadata to an <see cref="AdditionalPropertiesDictionary"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method can be replaced by the one from A2A SDK once it is public.
|
||||
/// </remarks>
|
||||
/// <param name="metadata">The metadata dictionary to convert.</param>
|
||||
/// <returns>The converted <see cref="AdditionalPropertiesDictionary"/>, or null if the input is null or empty.</returns>
|
||||
internal static AdditionalPropertiesDictionary? ToAdditionalProperties(this Dictionary<string, JsonElement>? metadata)
|
||||
{
|
||||
if (metadata is not { Count: > 0 })
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var additionalProperties = new AdditionalPropertiesDictionary();
|
||||
foreach (var kvp in metadata)
|
||||
{
|
||||
additionalProperties[kvp.Key] = kvp.Value;
|
||||
}
|
||||
return additionalProperties;
|
||||
}
|
||||
}
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Agents.AI;
|
||||
|
||||
namespace Microsoft.Extensions.AI;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for AdditionalPropertiesDictionary.
|
||||
/// </summary>
|
||||
internal static class AdditionalPropertiesDictionaryExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts an <see cref="AdditionalPropertiesDictionary"/> to a dictionary of <see cref="JsonElement"/> values suitable for A2A metadata.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method can be replaced by the one from A2A SDK once it is available.
|
||||
/// </remarks>
|
||||
/// <param name="additionalProperties">The additional properties dictionary to convert, or <c>null</c>.</param>
|
||||
/// <returns>A dictionary of JSON elements representing the metadata, or <c>null</c> if the input is null or empty.</returns>
|
||||
internal static Dictionary<string, JsonElement>? ToA2AMetadata(this AdditionalPropertiesDictionary? additionalProperties)
|
||||
{
|
||||
if (additionalProperties is not { Count: > 0 })
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var metadata = new Dictionary<string, JsonElement>();
|
||||
|
||||
foreach (var kvp in additionalProperties)
|
||||
{
|
||||
if (kvp.Value is JsonElement)
|
||||
{
|
||||
metadata[kvp.Key] = (JsonElement)kvp.Value!;
|
||||
continue;
|
||||
}
|
||||
|
||||
metadata[kvp.Key] = JsonSerializer.SerializeToElement(kvp.Value, A2AJsonUtilities.DefaultOptions.GetTypeInfo(typeof(object)));
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
namespace Microsoft.Agents.AI.Hosting.A2A.Converters;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for A2A metadata dictionary.
|
||||
/// </summary>
|
||||
internal static class A2AMetadataExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a dictionary of metadata to an <see cref="AdditionalPropertiesDictionary"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method can be replaced by the one from A2A SDK once it is public.
|
||||
/// </remarks>
|
||||
/// <param name="metadata">The metadata dictionary to convert.</param>
|
||||
/// <returns>The converted <see cref="AdditionalPropertiesDictionary"/>, or null if the input is null or empty.</returns>
|
||||
internal static AdditionalPropertiesDictionary? ToAdditionalProperties(this Dictionary<string, JsonElement>? metadata)
|
||||
{
|
||||
if (metadata is not { Count: > 0 })
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var additionalProperties = new AdditionalPropertiesDictionary();
|
||||
foreach (var kvp in metadata)
|
||||
{
|
||||
additionalProperties[kvp.Key] = kvp.Value;
|
||||
}
|
||||
return additionalProperties;
|
||||
}
|
||||
}
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
namespace Microsoft.Agents.AI.Hosting.A2A.Converters;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for AdditionalPropertiesDictionary.
|
||||
/// </summary>
|
||||
internal static class AdditionalPropertiesDictionaryExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts an <see cref="AdditionalPropertiesDictionary"/> to a dictionary of <see cref="JsonElement"/> values suitable for A2A metadata.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method can be replaced by the one from A2A SDK once it is available.
|
||||
/// </remarks>
|
||||
/// <param name="additionalProperties">The additional properties dictionary to convert, or <c>null</c>.</param>
|
||||
/// <returns>A dictionary of JSON elements representing the metadata, or <c>null</c> if the input is null or empty.</returns>
|
||||
internal static Dictionary<string, JsonElement>? ToA2AMetadata(this AdditionalPropertiesDictionary? additionalProperties)
|
||||
{
|
||||
if (additionalProperties is not { Count: > 0 })
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var metadata = new Dictionary<string, JsonElement>();
|
||||
|
||||
foreach (var kvp in additionalProperties)
|
||||
{
|
||||
if (kvp.Value is JsonElement)
|
||||
{
|
||||
metadata[kvp.Key] = (JsonElement)kvp.Value!;
|
||||
continue;
|
||||
}
|
||||
|
||||
metadata[kvp.Key] = JsonSerializer.SerializeToElement(kvp.Value, A2AHostingJsonUtilities.DefaultOptions.GetTypeInfo(typeof(object)));
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.AI;
|
||||
@@ -222,31 +223,36 @@ public sealed class DefaultMcpToolHandler : IMcpToolHandler, IAsyncDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private static AIContent ConvertContentBlock(ContentBlock block)
|
||||
internal static AIContent ConvertContentBlock(ContentBlock block)
|
||||
{
|
||||
return block switch
|
||||
{
|
||||
TextContentBlock text => new TextContent(text.Text),
|
||||
ImageContentBlock image => CreateDataContentFromBase64(image.Data, image.MimeType ?? "image/*"),
|
||||
AudioContentBlock audio => CreateDataContentFromBase64(audio.Data, audio.MimeType ?? "audio/*"),
|
||||
ImageContentBlock image => CreateDataContent(image.Data, image.MimeType ?? "image/*"),
|
||||
AudioContentBlock audio => CreateDataContent(audio.Data, audio.MimeType ?? "audio/*"),
|
||||
_ => new TextContent(block.ToString() ?? string.Empty),
|
||||
};
|
||||
}
|
||||
|
||||
private static DataContent CreateDataContentFromBase64(string? base64Data, string mediaType)
|
||||
private static DataContent CreateDataContent(ReadOnlyMemory<byte> base64Utf8Data, string mediaType)
|
||||
{
|
||||
if (string.IsNullOrEmpty(base64Data))
|
||||
if (base64Utf8Data.IsEmpty)
|
||||
{
|
||||
return new DataContent($"data:{mediaType};base64,", mediaType);
|
||||
}
|
||||
|
||||
#if NET8_0_OR_GREATER
|
||||
string base64 = Encoding.UTF8.GetString(base64Utf8Data.Span);
|
||||
#else
|
||||
string base64 = Encoding.UTF8.GetString(base64Utf8Data.ToArray());
|
||||
#endif
|
||||
|
||||
// If it's already a data URI, use it directly
|
||||
if (base64Data.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
|
||||
if (base64.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new DataContent(base64Data, mediaType);
|
||||
return new DataContent(base64, mediaType);
|
||||
}
|
||||
|
||||
// Otherwise, construct a data URI from the base64 data
|
||||
return new DataContent($"data:{mediaType};base64,{base64Data}", mediaType);
|
||||
return new DataContent($"data:{mediaType};base64,{base64}", mediaType);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user