.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
@@ -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
{