.NET Workflows - Enhance support and validation for image input (#1274)

* Updated

* Comments

* Namespace

* Comment

* Cleanup

* Update agent definition

* Disable

* Config

* Enable
This commit is contained in:
Chris
2025-10-08 00:00:34 +00:00
committed by GitHub
parent 362652b966
commit eb049c43a6
17 changed files with 339 additions and 189 deletions
@@ -78,6 +78,7 @@ public sealed class AzureAgentProvider(string projectEndpoint, TokenCredential p
TextContent textContent => new MessageInputTextBlock(textContent.Text),
HostedFileContent fileContent => new MessageInputImageFileBlock(new MessageImageFileParam(fileContent.FileId)),
UriContent uriContent when uriContent.Uri is not null => new MessageInputImageUriBlock(new MessageImageUriParam(uriContent.Uri.ToString())),
DataContent dataContent when dataContent.Uri is not null => new MessageInputImageUriBlock(new MessageImageUriParam(dataContent.Uri)),
_ => null // Unsupported content type
};
@@ -4,12 +4,21 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Azure.AI.Agents.Persistent;
using Microsoft.Extensions.AI;
namespace Microsoft.Agents.AI.Workflows.Declarative.Extensions;
internal static class AgentProviderExtensions
{
private static readonly HashSet<Azure.AI.Agents.Persistent.RunStatus> s_failureStatus =
[
Azure.AI.Agents.Persistent.RunStatus.Failed,
Azure.AI.Agents.Persistent.RunStatus.Cancelled,
Azure.AI.Agents.Persistent.RunStatus.Cancelling,
Azure.AI.Agents.Persistent.RunStatus.Expired,
];
public static async ValueTask<AgentRunResponse> InvokeAgentAsync(
this WorkflowAgentProvider agentProvider,
string executorId,
@@ -51,6 +60,13 @@ internal static class AgentProviderExtensions
updates.Add(update);
if (update.RawRepresentation is ChatResponseUpdate chatUpdate &&
chatUpdate.RawRepresentation is RunUpdate runUpdate &&
s_failureStatus.Contains(runUpdate.Value.Status))
{
throw new DeclarativeActionException($"Unexpected failure invoking agent, run {runUpdate.Value.Status}: {agent.Name ?? agent.Id} [{runUpdate.Value.Id}/{conversationId}]");
}
if (autoSend)
{
await context.AddEventAsync(new AgentRunUpdateEvent(executorId, update)).ConfigureAwait(false);
@@ -131,7 +131,7 @@ internal static class ChatMessageExtensions
return
contentType switch
{
AgentMessageContentType.ImageUrl => new UriContent(contentValue, "image/*"),
AgentMessageContentType.ImageUrl => GetImageContent(contentValue),
AgentMessageContentType.ImageFile => new HostedFileContent(contentValue),
_ => new TextContent(contentValue)
};
@@ -169,7 +169,7 @@ internal static class ChatMessageExtensions
yield return
contentItem?.GetProperty<StringDataValue>(TypeSchema.Message.Fields.ContentType)?.Value switch
{
TypeSchema.Message.ContentTypes.ImageUrl => new UriContent(contentValue.Value, "image/*"),
TypeSchema.Message.ContentTypes.ImageUrl => GetImageContent(contentValue.Value),
TypeSchema.Message.ContentTypes.ImageFile => new HostedFileContent(contentValue.Value),
_ => new TextContent(contentValue.Value)
};
@@ -177,6 +177,11 @@ internal static class ChatMessageExtensions
}
}
private static AIContent GetImageContent(string uriText) =>
uriText.StartsWith("data:", StringComparison.OrdinalIgnoreCase) ?
new DataContent(uriText, "image/*") :
new UriContent(uriText, "image/*");
private static TValue? GetProperty<TValue>(this RecordDataValue record, string name)
where TValue : DataValue
{
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(ProjectsTargetFrameworks)</TargetFrameworks>
@@ -21,16 +21,15 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents.Persistent" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.Bot.ObjectModel" />
<PackageReference Include="Microsoft.Bot.ObjectModel.Json" />
<PackageReference Include="Microsoft.Bot.ObjectModel.PowerFx" />
<PackageReference Include="Microsoft.PowerFx.Interpreter" />
<PackageReference Include="System.CodeDom" />
<PackageReference Include="System.Collections.Immutable" />
<PackageReference Include="Microsoft.Extensions.Configuration" />
<PackageReference Include="Microsoft.Extensions.Logging" />
<PackageReference Include="System.CodeDom" />
<PackageReference Include="System.Collections.Immutable" />
</ItemGroup>
<ItemGroup>