chore: import upstream snapshot with attribution
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:21:23 +08:00
commit b957a53def
5423 changed files with 863745 additions and 0 deletions
@@ -0,0 +1,33 @@
// Copyright (c) Microsoft. All rights reserved.
using System;
using Microsoft.SemanticKernel.ChatCompletion;
using ModelContextProtocol.Protocol;
namespace MCPClient;
/// <summary>
/// Extension methods for the <see cref="AuthorRole"/>.
/// </summary>
internal static class AuthorRoleExtensions
{
/// <summary>
/// Converts a <see cref="AuthorRole"/> to a <see cref="Role"/>.
/// </summary>
/// <param name="role">The author role to convert.</param>
/// <returns>The corresponding <see cref="Role"/>.</returns>
public static Role ToMCPRole(this AuthorRole role)
{
if (role == AuthorRole.User)
{
return Role.User;
}
if (role == AuthorRole.Assistant)
{
return Role.Assistant;
}
throw new InvalidOperationException($"Unexpected role '{role}'");
}
}
@@ -0,0 +1,62 @@
// Copyright (c) Microsoft. All rights reserved.
using System;
using System.Linq;
using Microsoft.SemanticKernel;
using ModelContextProtocol.Protocol;
namespace MCPClient;
/// <summary>
/// Extension methods for <see cref="ChatMessageContent"/>.
/// </summary>
public static class ChatMessageContentExtensions
{
/// <summary>
/// Converts a <see cref="ChatMessageContent"/> to a <see cref="CreateMessageResult"/>.
/// </summary>
/// <param name="chatMessageContent">The <see cref="ChatMessageContent"/> to convert.</param>
/// <returns>The corresponding <see cref="CreateMessageResult"/>.</returns>
public static CreateMessageResult ToCreateMessageResult(this ChatMessageContent chatMessageContent)
{
// Using the same heuristic as in the original MCP SDK code: McpClientExtensions.ToCreateMessageResult for consistency.
// ChatMessageContent can contain multiple items of different modalities, while the CreateMessageResult
// can only have a single content type: text, image, or audio. First, look for image or audio content,
// and if not found, fall back to the text content type by concatenating the text of all text contents.
ContentBlock? content = null;
foreach (KernelContent item in chatMessageContent.Items)
{
if (item is ImageContent image)
{
content = new ImageContentBlock
{
Data = Convert.ToBase64String(image.Data!.Value.Span),
MimeType = image.MimeType ?? "image/jpeg"
};
break;
}
else if (item is AudioContent audio)
{
content = new AudioContentBlock
{
Data = Convert.ToBase64String(audio.Data!.Value.Span),
MimeType = audio.MimeType ?? "audio/mpeg"
};
break;
}
}
content ??= new TextContentBlock
{
Text = string.Concat(chatMessageContent.Items.OfType<TextContent>()),
};
return new CreateMessageResult
{
Role = chatMessageContent.Role.ToMCPRole(),
Model = chatMessageContent.ModelId ?? "unknown",
Content = content
};
}
}
@@ -0,0 +1,29 @@
// Copyright (c) Microsoft. All rights reserved.
using System;
using Microsoft.SemanticKernel;
using ModelContextProtocol.Protocol;
namespace MCPClient;
/// <summary>
/// Extension methods for the <see cref="ContentBlock"/> class.
/// </summary>
public static class ContentBlockExtensions
{
/// <summary>
/// Converts a <see cref="ContentBlock"/> object to a <see cref="KernelContent"/> object.
/// </summary>
/// <param name="content">The <see cref="ContentBlock"/> object to convert.</param>
/// <returns>The corresponding <see cref="KernelContent"/> object.</returns>
public static KernelContent ToKernelContent(this ContentBlock content)
{
return content switch
{
TextContentBlock textContentBlock => new TextContent(textContentBlock.Text),
ImageContentBlock imageContentBlock => new ImageContent(Convert.FromBase64String(imageContentBlock.Data!), imageContentBlock.MimeType),
AudioContentBlock audioContentBlock => new AudioContent(Convert.FromBase64String(audioContentBlock.Data!), audioContentBlock.MimeType),
_ => throw new InvalidOperationException($"Unexpected message content type '{content.Type}'"),
};
}
}
@@ -0,0 +1,35 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Collections.Generic;
using System.Linq;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using ModelContextProtocol.Protocol;
namespace MCPClient;
/// <summary>
/// Extension methods for <see cref="GetPromptResult"/>.
/// </summary>
internal static class PromptResultExtensions
{
/// <summary>
/// Converts a <see cref="GetPromptResult"/> to chat message contents.
/// </summary>
/// <param name="result">The prompt result to convert.</param>
/// <returns>The corresponding <see cref="ChatHistory"/>.</returns>
public static IList<ChatMessageContent> ToChatMessageContents(this GetPromptResult result)
{
return [.. result.Messages.Select(ToChatMessageContent)];
}
/// <summary>
/// Converts a <see cref="PromptMessage"/> to a <see cref="ChatMessageContent"/>.
/// </summary>
/// <param name="message">The <see cref="PromptMessage"/> to convert.</param>
/// <returns>The corresponding <see cref="ChatMessageContent"/>.</returns>
public static ChatMessageContent ToChatMessageContent(this PromptMessage message)
{
return new ChatMessageContent(role: message.Role.ToAuthorRole(), items: [message.Content.ToKernelContent()]);
}
}
@@ -0,0 +1,80 @@
// Copyright (c) Microsoft. All rights reserved.
using System;
using System.Collections.Generic;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using ModelContextProtocol.Protocol;
namespace MCPClient;
/// <summary>
/// Extension methods for <see cref="ReadResourceResult"/>.
/// </summary>
public static class ReadResourceResultExtensions
{
/// <summary>
/// Converts a <see cref="ReadResourceResult"/> to a <see cref="ChatMessageContentItemCollection"/>.
/// </summary>
/// <param name="readResourceResult">The MCP read resource result to convert.</param>
/// <returns>The corresponding <see cref="ChatMessageContentItemCollection"/>.</returns>
public static ChatMessageContentItemCollection ToChatMessageContentItemCollection(this ReadResourceResult readResourceResult)
{
if (readResourceResult.Contents.Count == 0)
{
throw new InvalidOperationException("The resource does not contain any contents.");
}
ChatMessageContentItemCollection result = [];
foreach (var resourceContent in readResourceResult.Contents)
{
Dictionary<string, object?> metadata = new()
{
["uri"] = resourceContent.Uri
};
if (resourceContent is TextResourceContents textResourceContent)
{
result.Add(new TextContent()
{
Text = textResourceContent.Text,
MimeType = textResourceContent.MimeType,
Metadata = metadata,
});
}
else if (resourceContent is BlobResourceContents blobResourceContent)
{
if (blobResourceContent.MimeType?.StartsWith("image", System.StringComparison.InvariantCulture) ?? false)
{
result.Add(new ImageContent()
{
Data = Convert.FromBase64String(blobResourceContent.Blob),
MimeType = blobResourceContent.MimeType,
Metadata = metadata,
});
}
else if (blobResourceContent.MimeType?.StartsWith("audio", System.StringComparison.InvariantCulture) ?? false)
{
result.Add(new AudioContent
{
Data = Convert.FromBase64String(blobResourceContent.Blob),
MimeType = blobResourceContent.MimeType,
Metadata = metadata,
});
}
else
{
result.Add(new BinaryContent
{
Data = Convert.FromBase64String(blobResourceContent.Blob),
MimeType = blobResourceContent.MimeType,
Metadata = metadata,
});
}
}
}
return result;
}
}
@@ -0,0 +1,28 @@
// Copyright (c) Microsoft. All rights reserved.
using System;
using Microsoft.SemanticKernel.ChatCompletion;
using ModelContextProtocol.Protocol;
namespace MCPClient;
/// <summary>
/// Extension methods for the <see cref="Role"/> enum.
/// </summary>
internal static class RoleExtensions
{
/// <summary>
/// Converts a <see cref="Role"/> to a <see cref="AuthorRole"/>.
/// </summary>
/// <param name="role">The MCP role to convert.</param>
/// <returns>The corresponding <see cref="AuthorRole"/>.</returns>
public static AuthorRole ToAuthorRole(this Role role)
{
return role switch
{
Role.User => AuthorRole.User,
Role.Assistant => AuthorRole.Assistant,
_ => throw new InvalidOperationException($"Unexpected role '{role}'")
};
}
}
@@ -0,0 +1,34 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Collections.Generic;
using System.Linq;
using Microsoft.SemanticKernel;
using ModelContextProtocol.Protocol;
namespace MCPClient;
/// <summary>
/// Extension methods for <see cref="SamplingMessage"/>.
/// </summary>
public static class SamplingMessageExtensions
{
/// <summary>
/// Converts a collection of <see cref="SamplingMessage"/> to a list of <see cref="ChatMessageContent"/>.
/// </summary>
/// <param name="samplingMessages">The collection of <see cref="SamplingMessage"/> to convert.</param>
/// <returns>The corresponding list of <see cref="ChatMessageContent"/>.</returns>
public static List<ChatMessageContent> ToChatMessageContents(this IEnumerable<SamplingMessage> samplingMessages)
{
return [.. samplingMessages.Select(ToChatMessageContent)];
}
/// <summary>
/// Converts a <see cref="SamplingMessage"/> to a <see cref="ChatMessageContent"/>.
/// </summary>
/// <param name="message">The <see cref="SamplingMessage"/> to convert.</param>
/// <returns>The corresponding <see cref="ChatMessageContent"/>.</returns>
public static ChatMessageContent ToChatMessageContent(this SamplingMessage message)
{
return new ChatMessageContent(role: message.Role.ToAuthorRole(), items: [message.Content.ToKernelContent()]);
}
}