Skip to content

Commit 0965a83

Browse files
crickmanCopilot
andauthored
.NET Workflows - Update Declarative Integration Tests for File Cases (#2733)
* Updated * Update dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Agents/VisionAgentProvider.cs Co-authored-by: Copilot <[email protected]> * Consistency --------- Co-authored-by: Copilot <[email protected]>
1 parent 2caf1bb commit 0965a83

File tree

5 files changed

+75
-32
lines changed

5 files changed

+75
-32
lines changed

dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Agents/AgentProvider.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public static class Names
1616
public const string Marketing = "MARKETING";
1717
public const string MathChat = "MATHCHAT";
1818
public const string InputArguments = "INPUTARGUMENTS";
19+
public const string Vision = "VISION";
1920
}
2021

2122
public static class Settings
@@ -33,6 +34,7 @@ public static AgentProvider Create(IConfiguration configuration, string provider
3334
Names.Marketing => new MarketingAgentProvider(configuration),
3435
Names.MathChat => new MathChatAgentProvider(configuration),
3536
Names.InputArguments => new PoemAgentProvider(configuration),
37+
Names.Vision => new VisionAgentProvider(configuration),
3638
_ => new TestAgentProvider(configuration),
3739
};
3840

dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Agents/TestAgentProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ protected override async IAsyncEnumerable<AgentVersion> CreateAgentsAsync(Uri fo
2020
await aiProjectClient.CreateAgentAsync(
2121
agentName: "TestAgent",
2222
agentDefinition: this.DefineMenuAgent(),
23-
agentDescription: "Provides information about the restaurant menu");
23+
agentDescription: "Basic agent");
2424
}
2525

2626
private PromptAgentDefinition DefineMenuAgent() =>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
using System;
4+
using System.Collections.Generic;
5+
using Azure.AI.Projects;
6+
using Azure.AI.Projects.OpenAI;
7+
using Azure.Identity;
8+
using Microsoft.Extensions.Configuration;
9+
using Shared.Foundry;
10+
11+
namespace Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests.Agents;
12+
13+
internal sealed class VisionAgentProvider(IConfiguration configuration) : AgentProvider(configuration)
14+
{
15+
protected override async IAsyncEnumerable<AgentVersion> CreateAgentsAsync(Uri foundryEndpoint)
16+
{
17+
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
18+
19+
yield return
20+
await aiProjectClient.CreateAgentAsync(
21+
agentName: "VisionAgent",
22+
agentDefinition: this.DefineVisionAgent(),
23+
agentDescription: "Use computer vision to describe an image or document.");
24+
}
25+
26+
private PromptAgentDefinition DefineVisionAgent() =>
27+
new(this.GetSetting(Settings.FoundryModelFull))
28+
{
29+
Instructions =
30+
"""
31+
Describe the image or document contained in the user request, if any;
32+
otherwise, suggest that the user provide an image or document.
33+
""",
34+
};
35+
}

dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/MediaInputTest.cs

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Threading.Tasks;
77
using Azure.AI.Projects;
88
using Azure.Identity;
9+
using Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests.Agents;
910
using Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests.Framework;
1011
using Microsoft.Extensions.AI;
1112
using OpenAI.Files;
@@ -19,63 +20,72 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests;
1920
public sealed class MediaInputTest(ITestOutputHelper output) : IntegrationTest(output)
2021
{
2122
private const string WorkflowFileName = "MediaInput.yaml";
22-
private const string ImageReference = "https://sample-files.com/downloads/documents/pdf/basic-text.pdf";
23+
private const string PdfReference = "https://sample-files.com/downloads/documents/pdf/basic-text.pdf";
24+
private const string ImageReference = "https://sample-files.com/downloads/images/jpg/web_optimized_1200x800_97kb.jpg";
2325

24-
[Fact]
25-
public async Task ValidateImageUrlAsync()
26+
[Theory]
27+
[InlineData(ImageReference, "image/jpeg")]
28+
[InlineData(PdfReference, "application/pdf", Skip = "Not currently supported by agent service api")]
29+
public async Task ValidateFileUrlAsync(string fileSource, string mediaType)
2630
{
27-
this.Output.WriteLine($"Image: {ImageReference}");
28-
await this.ValidateImageAsync(new UriContent(ImageReference, "image/jpeg"));
31+
this.Output.WriteLine($"File: {ImageReference}");
32+
await this.ValidateFileAsync(new UriContent(fileSource, mediaType));
2933
}
3034

31-
[Fact]
32-
public async Task ValidateImageDataAsync()
35+
[Theory]
36+
[InlineData(ImageReference, "image/jpeg")]
37+
[InlineData(PdfReference, "application/pdf")]
38+
public async Task ValidateFileDataAsync(string fileSource, string mediaType)
3339
{
34-
byte[] imageData = await DownloadFileAsync();
35-
string encodedData = Convert.ToBase64String(imageData);
36-
string imageUrl = $"data:image/png;base64,{encodedData}";
37-
this.Output.WriteLine($"Image: {imageUrl.Substring(0, 112)}...");
38-
await this.ValidateImageAsync(new DataContent(imageUrl));
40+
byte[] fileData = await DownloadFileAsync(fileSource);
41+
string encodedData = Convert.ToBase64String(fileData);
42+
string fileUrl = $"data:{mediaType};base64,{encodedData}";
43+
this.Output.WriteLine($"Content: {fileUrl.Substring(0, 112)}...");
44+
await this.ValidateFileAsync(new DataContent(fileUrl));
3945
}
4046

41-
[Fact(Skip = "Not behaving will in git-hub build pipeline")]
42-
public async Task ValidateImageUploadAsync()
47+
[Fact(Skip = "Not currently supported by agent service api")]
48+
public async Task ValidateFileUploadAsync()
4349
{
44-
byte[] imageData = await DownloadFileAsync();
50+
byte[] fileData = await DownloadFileAsync(PdfReference);
4551
AIProjectClient client = new(this.TestEndpoint, new AzureCliCredential());
46-
using MemoryStream contentStream = new(imageData);
52+
using MemoryStream contentStream = new(fileData);
4753
OpenAIFileClient fileClient = client.GetProjectOpenAIClient().GetOpenAIFileClient();
4854
OpenAIFile fileInfo = await fileClient.UploadFileAsync(contentStream, "basic-text.pdf", FileUploadPurpose.Assistants);
4955
try
5056
{
51-
this.Output.WriteLine($"Image: {fileInfo.Id}");
52-
await this.ValidateImageAsync(new HostedFileContent(fileInfo.Id));
57+
this.Output.WriteLine($"File: {fileInfo.Id}");
58+
await this.ValidateFileAsync(new HostedFileContent(fileInfo.Id));
5359
}
5460
finally
5561
{
5662
await fileClient.DeleteFileAsync(fileInfo.Id);
5763
}
5864
}
5965

60-
private static async Task<byte[]> DownloadFileAsync()
66+
private static async Task<byte[]> DownloadFileAsync(string uri)
6167
{
6268
using HttpClient client = new();
6369
client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0");
64-
return await client.GetByteArrayAsync(new Uri(ImageReference));
70+
return await client.GetByteArrayAsync(new Uri(uri));
6571
}
6672

67-
private async Task ValidateImageAsync(AIContent imageContent)
73+
private async Task ValidateFileAsync(AIContent fileContent)
6874
{
69-
ChatMessage inputMessage = new(ChatRole.User, [new TextContent("Here is my image:"), imageContent]);
75+
AgentProvider agentProvider = AgentProvider.Create(this.Configuration, AgentProvider.Names.Vision);
76+
await agentProvider.CreateAgentsAsync().ConfigureAwait(false);
77+
78+
ChatMessage inputMessage = new(ChatRole.User, [new TextContent("I've provided a file:"), fileContent]);
7079

7180
DeclarativeWorkflowOptions options = await this.CreateOptionsAsync();
7281
Workflow workflow = DeclarativeWorkflowBuilder.Build<ChatMessage>(Path.Combine(Environment.CurrentDirectory, "Workflows", WorkflowFileName), options);
7382

7483
WorkflowHarness harness = new(workflow, runId: Path.GetFileNameWithoutExtension(WorkflowFileName));
7584
WorkflowEvents workflowEvents = await harness.RunWorkflowAsync(inputMessage).ConfigureAwait(false);
76-
Assert.Single(workflowEvents.ConversationEvents);
77-
this.Output.WriteLine("CONVERSATION: " + workflowEvents.ConversationEvents[0].ConversationId);
78-
Assert.Single(workflowEvents.AgentResponseEvents);
79-
this.Output.WriteLine("RESPONSE: " + workflowEvents.AgentResponseEvents[0].Response.Text);
85+
ConversationUpdateEvent conversationEvent = Assert.Single(workflowEvents.ConversationEvents);
86+
this.Output.WriteLine("CONVERSATION: " + conversationEvent.ConversationId);
87+
AgentRunResponseEvent agentResponseEvent = Assert.Single(workflowEvents.AgentResponseEvents);
88+
this.Output.WriteLine("RESPONSE: " + agentResponseEvent.Response.Text);
89+
Assert.NotEmpty(agentResponseEvent.Response.Text);
8090
}
8191
}

dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Workflows/MediaInput.yaml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,4 @@ trigger:
99
id: invoke_vision
1010
conversationId: =System.ConversationId
1111
agent:
12-
name: TestAgent
13-
input:
14-
additionalInstructions: |-
15-
Describe the image contained in the user request, if any;
16-
otherwise, suggest that the user provide an image.
12+
name: VisionAgent

0 commit comments

Comments
 (0)