Allowed the Batch Processing assistant to process images (#1087)

Co-authored-by: Thorsten Sommer <SommerEngineering@users.noreply.github.com>
This commit is contained in:
Peer HogeterpandThorsten Sommer authored and GitHub committed 2026-10-21 13:52:26 +02:00
1 parent 5d6e48ef93
commit e019c24ea2
19 files changed
+429 -31

No files matched your search

@@ -1,6 +1,8 @@
using System.Diagnostics;
using System.Globalization;
using AIStudio.Settings;
namespace AIStudio.Assistants.BatchProcessing;
public partial class AssistantBatchProcessing
@@ -42,6 +44,7 @@ public partial class AssistantBatchProcessing
}
this.PrepareFileResults(resolvedOutputDirectory, files, previousLog, previousResults);
await this.WarnAboutUnreadableImagesAsync();
await this.CheckpointAssistantSession();
await this.RunBatchAsync(resolvedOutputDirectory);
}
@@ -88,6 +91,27 @@ public partial class AssistantBatchProcessing
}
}
/// <summary>
/// Tells the user before the first file when the images of the run will fail, because the
/// selected model cannot read images.
/// </summary>
/// <remarks>
/// Counts only the images which this run still processes. Images done by an earlier run of a
/// continued batch keep their results and do not fail.
/// </remarks>
private async Task WarnAboutUnreadableImagesAsync()
{
var numImages = this.fileResults.Count(fileResult => fileResult.Status is not BatchProcessingFileStatus.DONE && IsImage(fileResult.FilePath));
if (numImages == 0 || this.ProviderSettings.SupportsImageInput())
return;
var warning = numImages == 1
? T("The selected model cannot read images, so the image among the selected files will fail. All other files are processed as usual.")
: string.Format(T("The selected model cannot read images, so the {0} images among the selected files will fail. All other files are processed as usual."), numImages);
await this.MessageBus.SendWarning(new(Icons.Material.Filled.ImageNotSupported, warning));
}
/// <summary>
/// Processes all documents which are not restored from a previous run.
/// </summary>
@@ -188,14 +212,14 @@ public partial class AssistantBatchProcessing
/// </remarks>
private async Task ProcessOneFileAsync(BatchProcessingFileResult fileResult, string resolvedOutputDirectory, CancellationToken token)
{
var fileContent = await this.LoadInputContentAsync(fileResult, token);
if (fileContent is null)
var input = await this.LoadInputContentAsync(fileResult, token);
if (input is null)
return;
string aiAnswer;
try
{
(aiAnswer, fileResult.UsedTools) = await this.CallAIAsync(fileResult.FileName, fileContent, token);
(aiAnswer, fileResult.UsedTools) = await this.CallAIAsync(fileResult.FileName, input.Value, token);
}
catch (OperationCanceledException)
{
@@ -217,6 +241,17 @@ public partial class AssistantBatchProcessing
return;
}
//
// The request reads the image anew in every round with the model, e.g., after each tool
// call, and quietly leaves out an image which is gone by then. The answer would be about
// nothing and must not count as a result, so that continuing the run processes the image again:
//
if (input.Value.Image is { Exists: false })
{
this.FinishFileResult(fileResult, BatchProcessingFileStatus.FAILED, T("The image was no longer available while the model was asked about it."));
return;
}
if (string.IsNullOrWhiteSpace(aiAnswer))
{
this.FinishFileResult(fileResult, BatchProcessingFileStatus.FAILED, T("The AI answer was empty."));