sozsoft-platform/api/modules/Sozsoft.Mcp/Sozsoft.Mcp.Application/McpDevRequestImages.cs

54 lines
1.9 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Sozsoft.Mcp.Dtos;
namespace Sozsoft.Mcp;
/// <summary>
/// Talep aciklamasina yapistirilan gorseller HtmlEditor'da base64 <c>data:</c> URI olarak
/// saklanir. Model bu metni resim olarak goremez; gorseller ayiklanip MCP gorsel icerigi olarak
/// iletilir, metinde yerlerine bir isaret kalir. Yalnizca modelin okuyabildigi bicimler ayiklanir;
/// digerleri (svg gibi) metinde oldugu gibi birakilir.
/// </summary>
internal static partial class McpDevRequestImages
{
private static readonly HashSet<string> SupportedMimeTypes = new(StringComparer.OrdinalIgnoreCase)
{
"image/png", "image/jpeg", "image/gif", "image/webp"
};
[GeneratedRegex("""<img\b[^>]*?\bsrc\s*=\s*["']data:(?<mime>image/[\w.+-]+);base64,(?<data>[^"']+)["'][^>]*>""", RegexOptions.IgnoreCase)]
private static partial Regex EmbeddedImage();
public static (string? Html, List<McpDevRequestImageDto> Images) Extract(string? html)
{
var images = new List<McpDevRequestImageDto>();
if (string.IsNullOrEmpty(html))
{
return (html, images);
}
var text = EmbeddedImage().Replace(html, match =>
{
var mimeType = match.Groups["mime"].Value.ToLowerInvariant();
var data = Regex.Replace(match.Groups["data"].Value, @"\s+", string.Empty);
if (!SupportedMimeTypes.Contains(mimeType) || !IsBase64(data))
{
return match.Value;
}
var placeholder = $"[image-{images.Count + 1}]";
images.Add(new McpDevRequestImageDto { Placeholder = placeholder, MimeType = mimeType, Data = data });
return placeholder;
});
return (text, images);
}
private static bool IsBase64(string data)
=> Convert.TryFromBase64String(data, new byte[data.Length * 3 / 4], out _);
}