mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-02-12 20:01:37 +00:00
Refactor image conversion to return success status and base64 content
This commit is contained in:
parent
839ba3aaf0
commit
011b3a8d04
@ -159,7 +159,9 @@ public sealed class AgentDataSourceSelection (ILogger<AgentDataSourceSelection>
|
||||
ContentText text => text.Text,
|
||||
|
||||
// Image prompts may be empty, e.g., when the image is too large:
|
||||
ContentImage image => await image.AsBase64(token),
|
||||
ContentImage image => await image.TryAsBase64(token) is (success: true, { } base64Image)
|
||||
? base64Image
|
||||
: string.Empty,
|
||||
|
||||
// Other content types are not supported yet:
|
||||
_ => string.Empty,
|
||||
|
||||
@ -219,7 +219,9 @@ public sealed class AgentRetrievalContextValidation (ILogger<AgentRetrievalConte
|
||||
ContentText text => text.Text,
|
||||
|
||||
// Image prompts may be empty, e.g., when the image is too large:
|
||||
ContentImage image => await image.AsBase64(token),
|
||||
ContentImage image => await image.TryAsBase64(token) is (success: true, { } base64Image)
|
||||
? base64Image
|
||||
: string.Empty,
|
||||
|
||||
// Other content types are not supported yet:
|
||||
_ => string.Empty,
|
||||
|
||||
@ -238,7 +238,7 @@ public sealed record ChatThread
|
||||
{
|
||||
var (contentData, contentType) = block.Content switch
|
||||
{
|
||||
ContentImage image => (await image.AsBase64(token), Tools.ERIClient.DataModel.ContentType.IMAGE),
|
||||
ContentImage image => (await image.TryAsBase64(token) is (success: true, { } base64Image) ? base64Image : string.Empty, Tools.ERIClient.DataModel.ContentType.IMAGE),
|
||||
ContentText text => (text.Text, Tools.ERIClient.DataModel.ContentType.TEXT),
|
||||
|
||||
_ => (string.Empty, Tools.ERIClient.DataModel.ContentType.UNKNOWN),
|
||||
|
||||
@ -12,21 +12,25 @@ public static class IImageSourceExtensions
|
||||
/// <remarks>
|
||||
/// The images are directly converted to base64 strings. The maximum
|
||||
/// size of the image is around 10 MB. If the image is larger, the method
|
||||
/// returns an empty string.
|
||||
///
|
||||
/// returns an empty string.<br/>
|
||||
/// <br/>
|
||||
/// As of now, this method does no sort of image processing. LLMs usually
|
||||
/// do not work with arbitrary image sizes. In the future, we might have
|
||||
/// to resize the images before sending them to the model.
|
||||
/// to resize the images before sending them to the model.<br/>
|
||||
/// <br/>
|
||||
/// Note as well that this method returns just the base64 string without
|
||||
/// any data URI prefix (like "data:image/png;base64,"). The caller has
|
||||
/// to take care of that if needed.
|
||||
/// </remarks>
|
||||
/// <param name="image">The image source.</param>
|
||||
/// <param name="token">The cancellation token.</param>
|
||||
/// <returns>The image content as a base64 string; might be empty.</returns>
|
||||
public static async Task<string> AsBase64(this IImageSource image, CancellationToken token = default)
|
||||
public static async Task<(bool success, string base64Content)> TryAsBase64(this IImageSource image, CancellationToken token = default)
|
||||
{
|
||||
switch (image.SourceType)
|
||||
{
|
||||
case ContentImageSource.BASE64:
|
||||
return image.Source;
|
||||
return (success: true, image.Source);
|
||||
|
||||
case ContentImageSource.URL:
|
||||
{
|
||||
@ -39,14 +43,15 @@ public static class IImageSourceExtensions
|
||||
if(lengthBytes > 10_000_000)
|
||||
{
|
||||
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.ImageNotSupported, TB("The image at the URL is too large (>10 MB). Skipping the image.")));
|
||||
return string.Empty;
|
||||
return (success: false, string.Empty);
|
||||
}
|
||||
|
||||
var bytes = await response.Content.ReadAsByteArrayAsync(token);
|
||||
return Convert.ToBase64String(bytes);
|
||||
return (success: true, Convert.ToBase64String(bytes));
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.ImageNotSupported, TB("Failed to download the image from the URL. Skipping the image.")));
|
||||
return (success: false, string.Empty);
|
||||
}
|
||||
|
||||
case ContentImageSource.LOCAL_PATH:
|
||||
@ -57,17 +62,18 @@ public static class IImageSourceExtensions
|
||||
if(length > 10_000_000)
|
||||
{
|
||||
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.ImageNotSupported, TB("The local image file is too large (>10 MB). Skipping the image.")));
|
||||
return string.Empty;
|
||||
return (success: false, string.Empty);
|
||||
}
|
||||
|
||||
var bytes = await File.ReadAllBytesAsync(image.Source, token);
|
||||
return Convert.ToBase64String(bytes);
|
||||
return (success: true, Convert.ToBase64String(bytes));
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.ImageNotSupported, TB("The local image file does not exist. Skipping the image.")));
|
||||
return (success: false, string.Empty);
|
||||
|
||||
default:
|
||||
return string.Empty;
|
||||
return (success: false, string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -74,7 +74,9 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource
|
||||
LatestUserPrompt = lastUserPrompt switch
|
||||
{
|
||||
ContentText text => text.Text,
|
||||
ContentImage image => await image.AsBase64(token),
|
||||
ContentImage image => await image.TryAsBase64(token) is (success: true, { } base64Image)
|
||||
? base64Image
|
||||
: string.Empty,
|
||||
_ => string.Empty
|
||||
},
|
||||
|
||||
|
||||
@ -81,7 +81,9 @@ public static class IRetrievalContextExtensions
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Matched image content as base64-encoded data:");
|
||||
sb.AppendLine("````");
|
||||
sb.AppendLine(await imageContext.AsBase64(token));
|
||||
sb.AppendLine(await imageContext.TryAsBase64(token) is (success: true, { } base64Image)
|
||||
? base64Image
|
||||
: string.Empty);
|
||||
sb.AppendLine("````");
|
||||
break;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user