mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Update Microsoft.Agents.AI.AzureAI for Azure.AI.Projects SDK 2.0.0
- Bump Azure.AI.Projects to 2.0.0-alpha.20260213.1 - Bump Azure.AI.Projects.OpenAI to 2.0.0-alpha.20260213.1 - Bump System.ClientModel to 1.9.0 (transitive dependency) - Switch both GetAgent and CreateAgentVersion to protocol methods with MEAI user-agent policy injection via RequestOptions - Migrate 29 CREATE-path tests from FakeAgentClient to HttpHandlerAssert pattern for real HTTP pipeline testing - Fix StructuredOutputDefinition constructor (BinaryData -> IDictionary) - Fix responses endpoint path (openai/responses -> /responses) - Add local-packages NuGet source for pre-release nupkgs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -19,8 +19,8 @@
|
||||
<PackageVersion Include="Aspire.Microsoft.Azure.Cosmos" Version="$(AspireAppHostSdkVersion)" />
|
||||
<PackageVersion Include="CommunityToolkit.Aspire.OllamaSharp" Version="13.0.0" />
|
||||
<!-- Azure.* -->
|
||||
<PackageVersion Include="Azure.AI.Projects" Version="1.2.0-beta.5" />
|
||||
<PackageVersion Include="Azure.AI.Projects.OpenAI" Version="1.0.0-beta.5" />
|
||||
<PackageVersion Include="Azure.AI.Projects" Version="2.0.0-alpha.20260213.1" />
|
||||
<PackageVersion Include="Azure.AI.Projects.OpenAI" Version="2.0.0-alpha.20260213.1" />
|
||||
<PackageVersion Include="Azure.AI.Agents.Persistent" Version="1.2.0-beta.8" />
|
||||
<PackageVersion Include="Azure.AI.OpenAI" Version="2.8.0-beta.1" />
|
||||
<PackageVersion Include="Azure.Identity" Version="1.17.1" />
|
||||
@@ -35,7 +35,7 @@
|
||||
<!-- System.* -->
|
||||
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="10.0.3" />
|
||||
<PackageVersion Include="Microsoft.Bcl.HashCode" Version="6.0.0" />
|
||||
<PackageVersion Include="System.ClientModel" Version="1.8.1" />
|
||||
<PackageVersion Include="System.ClientModel" Version="1.9.0" />
|
||||
<PackageVersion Include="System.CodeDom" Version="10.0.0" />
|
||||
<PackageVersion Include="System.Collections.Immutable" Version="10.0.1" />
|
||||
<PackageVersion Include="System.CommandLine" Version="2.0.0-rc.2.25502.107" />
|
||||
|
||||
@@ -3,10 +3,15 @@
|
||||
<packageSources>
|
||||
<clear />
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||
<add key="local-packages" value="D:\local-packages" />
|
||||
</packageSources>
|
||||
<packageSourceMapping>
|
||||
<packageSource key="nuget.org">
|
||||
<package pattern="*" />
|
||||
</packageSource>
|
||||
<packageSource key="local-packages">
|
||||
<package pattern="Azure.AI.Projects" />
|
||||
<package pattern="Azure.AI.Projects.OpenAI" />
|
||||
</packageSource>
|
||||
</packageSourceMapping>
|
||||
</configuration>
|
||||
@@ -39,7 +39,7 @@ public static partial class AzureAIProjectChatClientExtensions
|
||||
/// <exception cref="InvalidOperationException">The agent with the specified name was not found.</exception>
|
||||
/// <remarks>
|
||||
/// When instantiating a <see cref="ChatClientAgent"/> by using an <see cref="AgentReference"/>, minimal information will be available about the agent in the instance level, and any logic that relies
|
||||
/// on <see cref="AIAgent.GetService(Type, object?)"/> to retrieve information about the agent like <see cref="AgentVersion" /> will receive <see langword="null"/> as the result.
|
||||
/// on <see cref="AIAgent.GetService{TService}(object?)"/> to retrieve information about the agent like <see cref="AgentVersion" /> will receive <see langword="null"/> as the result.
|
||||
/// </remarks>
|
||||
public static ChatClientAgent AsAIAgent(
|
||||
this AIProjectClient aiProjectClient,
|
||||
@@ -352,33 +352,32 @@ public static partial class AzureAIProjectChatClientExtensions
|
||||
|
||||
#region Private
|
||||
|
||||
private static readonly ModelReaderWriterOptions s_modelWriterOptionsWire = new("W");
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves an agent record by name using the Protocol method with user-agent header.
|
||||
/// Asynchronously retrieves an agent record by name using the protocol method to inject user-agent headers.
|
||||
/// </summary>
|
||||
private static async Task<AgentRecord> GetAgentRecordByNameAsync(AIProjectClient aiProjectClient, string agentName, CancellationToken cancellationToken)
|
||||
{
|
||||
ClientResult protocolResponse = await aiProjectClient.Agents.GetAgentAsync(agentName, cancellationToken.ToRequestOptions(false)).ConfigureAwait(false);
|
||||
var rawResponse = protocolResponse.GetRawResponse();
|
||||
AgentRecord? result = ModelReaderWriter.Read<AgentRecord>(rawResponse.Content, s_modelWriterOptionsWire, AzureAIProjectsOpenAIContext.Default);
|
||||
return ClientResult.FromOptionalValue(result, rawResponse).Value!
|
||||
?? throw new InvalidOperationException($"Agent with name '{agentName}' not found.");
|
||||
return result ?? throw new InvalidOperationException($"Agent with name '{agentName}' not found.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously creates an agent version using the Protocol method with user-agent header.
|
||||
/// Asynchronously creates an agent version using the protocol method to inject user-agent headers.
|
||||
/// </summary>
|
||||
private static async Task<AgentVersion> CreateAgentVersionWithProtocolAsync(AIProjectClient aiProjectClient, string agentName, AgentVersionCreationOptions creationOptions, CancellationToken cancellationToken)
|
||||
{
|
||||
using BinaryContent protocolRequest = BinaryContent.Create(ModelReaderWriter.Write(creationOptions, ModelReaderWriterOptions.Json, AzureAIProjectsContext.Default));
|
||||
ClientResult protocolResponse = await aiProjectClient.Agents.CreateAgentVersionAsync(agentName, protocolRequest, cancellationToken.ToRequestOptions(false)).ConfigureAwait(false);
|
||||
|
||||
BinaryData serializedOptions = ModelReaderWriter.Write(creationOptions, s_modelWriterOptionsWire, AzureAIProjectsContext.Default);
|
||||
BinaryContent content = BinaryContent.Create(serializedOptions);
|
||||
ClientResult protocolResponse = await aiProjectClient.Agents.CreateAgentVersionAsync(agentName, content, foundryFeatures: null, cancellationToken.ToRequestOptions(false)).ConfigureAwait(false);
|
||||
var rawResponse = protocolResponse.GetRawResponse();
|
||||
AgentVersion? result = ModelReaderWriter.Read<AgentVersion>(rawResponse.Content, s_modelWriterOptionsWire, AzureAIProjectsOpenAIContext.Default);
|
||||
return ClientResult.FromValue(result, rawResponse).Value!;
|
||||
return result ?? throw new InvalidOperationException($"Failed to create agent version for agent '{agentName}'.");
|
||||
}
|
||||
|
||||
private static readonly ModelReaderWriterOptions s_modelWriterOptionsWire = new("W");
|
||||
|
||||
private static async Task<ChatClientAgent> CreateAIAgentAsync(
|
||||
this AIProjectClient aiProjectClient,
|
||||
string name,
|
||||
|
||||
+116
-76
@@ -467,7 +467,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithModelAndOptions_CreatesValidAgentAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", instructions: "Test instructions");
|
||||
using var testClient = CreateTestAgentClientWithHandler(agentName: "test-agent", instructions: "Test instructions");
|
||||
var options = new ChatClientAgentOptions
|
||||
{
|
||||
Name = "test-agent",
|
||||
@@ -475,7 +475,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
};
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-model", options);
|
||||
var agent = await testClient.Client.CreateAIAgentAsync("test-model", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -490,7 +490,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithModelAndOptions_WithClientFactory_AppliesFactoryCorrectlyAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", instructions: "Test instructions");
|
||||
using var testClient = CreateTestAgentClientWithHandler(agentName: "test-agent", instructions: "Test instructions");
|
||||
var options = new ChatClientAgentOptions
|
||||
{
|
||||
Name = "test-agent",
|
||||
@@ -499,7 +499,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
TestChatClient? testChatClient = null;
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync(
|
||||
var agent = await testClient.Client.CreateAIAgentAsync(
|
||||
"test-model",
|
||||
options,
|
||||
clientFactory: (innerClient) => testChatClient = new TestChatClient(innerClient));
|
||||
@@ -560,12 +560,12 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithDefinition_CreatesAgentSuccessfullyAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient();
|
||||
using var testClient = CreateTestAgentClientWithHandler();
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
var options = new AgentVersionCreationOptions(definition);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", options);
|
||||
var agent = await testClient.Client.CreateAIAgentAsync("test-agent", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -582,12 +582,12 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
|
||||
var definitionResponse = GeneratePromptDefinitionResponse(definition, null);
|
||||
AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
using var testClient = CreateTestAgentClientWithHandler(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
|
||||
var options = new AgentVersionCreationOptions(definition);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", options);
|
||||
var agent = await testClient.Client.CreateAIAgentAsync("test-agent", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -602,12 +602,12 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
{
|
||||
// Arrange
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", agentDefinitionResponse: definition);
|
||||
using var testClient = CreateTestAgentClientWithHandler(agentName: "test-agent", agentDefinitionResponse: definition);
|
||||
|
||||
var options = new AgentVersionCreationOptions(definition);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", options);
|
||||
var agent = await testClient.Client.CreateAIAgentAsync("test-agent", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -628,12 +628,12 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
|
||||
// Create a response definition with the same tool
|
||||
var definitionResponse = GeneratePromptDefinitionResponse(definition, definition.Tools.Select(t => t.AsAITool()).ToList());
|
||||
AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
using var testClient = CreateTestAgentClientWithHandler(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
|
||||
var options = new AgentVersionCreationOptions(definition);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", options);
|
||||
var agent = await testClient.Client.CreateAIAgentAsync("test-agent", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -667,12 +667,12 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
definitionResponse.Tools.Add(tool);
|
||||
}
|
||||
|
||||
AIProjectClient client = this.CreateTestAgentClient(agentDefinitionResponse: definitionResponse);
|
||||
using var testClient = CreateTestAgentClientWithHandler(agentDefinitionResponse: definitionResponse);
|
||||
|
||||
var options = new AgentVersionCreationOptions(definition);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", options);
|
||||
var agent = await testClient.Client.CreateAIAgentAsync("test-agent", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -803,10 +803,10 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
|
||||
var definitionResponse = GeneratePromptDefinitionResponse(new PromptAgentDefinition("test-model") { Instructions = "Test instructions" }, tools);
|
||||
|
||||
AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
using var testClient = CreateTestAgentClientWithHandler(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync(
|
||||
var agent = await testClient.Client.CreateAIAgentAsync(
|
||||
"test-agent",
|
||||
"test-model",
|
||||
"Test instructions",
|
||||
@@ -831,14 +831,14 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithDefinitionTools_CreatesAgentAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient();
|
||||
using var testClient = CreateTestAgentClientWithHandler();
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" };
|
||||
definition.Tools.Add(ResponseTool.CreateFunctionTool("async_tool", BinaryData.FromString("{}"), strictModeEnabled: false));
|
||||
|
||||
var options = new AgentVersionCreationOptions(definition);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", options);
|
||||
var agent = await testClient.Client.CreateAIAgentAsync("test-agent", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -885,7 +885,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
var sharepointOptions = new SharePointGroundingToolOptions();
|
||||
sharepointOptions.ProjectConnections.Add(new ToolProjectConnection("connection-id"));
|
||||
|
||||
var structuredOutputs = new StructuredOutputDefinition("name", "description", BinaryData.FromString(AIJsonUtilities.CreateJsonSchema(new { id = "test" }.GetType()).ToString()), false);
|
||||
var structuredOutputs = new StructuredOutputDefinition("name", "description", new Dictionary<string, BinaryData> { ["schema"] = BinaryData.FromString(AIJsonUtilities.CreateJsonSchema(new { id = "test" }.GetType()).ToString()) }, false);
|
||||
|
||||
// Add tools to the definition
|
||||
definition.Tools.Add(ResponseTool.CreateFunctionTool("create_tool", BinaryData.FromString("{}"), strictModeEnabled: false));
|
||||
@@ -902,12 +902,12 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
// Generate agent definition response with the tools
|
||||
var definitionResponse = GeneratePromptDefinitionResponse(definition, definition.Tools.Select(t => t.AsAITool()).ToList());
|
||||
|
||||
AIProjectClient client = this.CreateTestAgentClient(agentDefinitionResponse: definitionResponse);
|
||||
using var testClient = CreateTestAgentClientWithHandler(agentDefinitionResponse: definitionResponse);
|
||||
|
||||
var options = new AgentVersionCreationOptions(definition);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", options);
|
||||
var agent = await testClient.Client.CreateAIAgentAsync("test-agent", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -942,12 +942,12 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
var definitionResponse = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
definitionResponse.Tools.Add(functionTool);
|
||||
|
||||
AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
using var testClient = CreateTestAgentClientWithHandler(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
|
||||
var options = new AgentVersionCreationOptions(definition);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", options);
|
||||
var agent = await testClient.Client.CreateAIAgentAsync("test-agent", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -961,7 +961,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithDeclarativeFunctionFromDefinition_AcceptsDeclarativeFunctionAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient();
|
||||
using var testClient = CreateTestAgentClientWithHandler();
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
|
||||
// Create a declarative function (not invocable) using AIFunctionFactory.CreateDeclaration
|
||||
@@ -974,7 +974,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
var options = new AgentVersionCreationOptions(definition);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", options);
|
||||
var agent = await testClient.Client.CreateAIAgentAsync("test-agent", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -1001,12 +1001,12 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
var definitionResponse = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
definitionResponse.Tools.Add(declarativeFunction.AsOpenAIResponseTool() ?? throw new InvalidOperationException());
|
||||
|
||||
AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
using var testClient = CreateTestAgentClientWithHandler(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
|
||||
var options = new AgentVersionCreationOptions(definition);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", options);
|
||||
var agent = await testClient.Client.CreateAIAgentAsync("test-agent", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -1027,12 +1027,12 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test instructions" };
|
||||
|
||||
var definitionResponse = GeneratePromptDefinitionResponse(definition, null);
|
||||
AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
using var testClient = CreateTestAgentClientWithHandler(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
|
||||
var options = new AgentVersionCreationOptions(definition);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-agent", options);
|
||||
var agent = await testClient.Client.CreateAIAgentAsync("test-agent", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -1083,7 +1083,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
new PromptAgentDefinition("test-model") { Instructions = "Test" },
|
||||
tools);
|
||||
|
||||
AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
using var testClient = CreateTestAgentClientWithHandler(agentName: "test-agent", agentDefinitionResponse: definitionResponse);
|
||||
|
||||
var options = new ChatClientAgentOptions
|
||||
{
|
||||
@@ -1092,7 +1092,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
};
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync("test-model", options);
|
||||
var agent = await testClient.Client.CreateAIAgentAsync("test-model", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -1278,14 +1278,14 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithClientFactory_ReceivesCorrectUnderlyingClientAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient();
|
||||
using var testClient = CreateTestAgentClientWithHandler();
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
IChatClient? receivedClient = null;
|
||||
|
||||
var options = new AgentVersionCreationOptions(definition);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync(
|
||||
var agent = await testClient.Client.CreateAIAgentAsync(
|
||||
"test-agent",
|
||||
options,
|
||||
clientFactory: (innerClient) =>
|
||||
@@ -1340,10 +1340,10 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
const string AgentName = "test-agent";
|
||||
const string Model = "test-model";
|
||||
const string Instructions = "Test instructions";
|
||||
AIProjectClient client = this.CreateTestAgentClient(AgentName, Instructions);
|
||||
using var testClient = CreateTestAgentClientWithHandler(AgentName, Instructions);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync(
|
||||
var agent = await testClient.Client.CreateAIAgentAsync(
|
||||
AgentName,
|
||||
Model,
|
||||
Instructions,
|
||||
@@ -1367,12 +1367,12 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
var definition = new PromptAgentDefinition("test-model") { Instructions = "Test" };
|
||||
|
||||
var agentDefinitionResponse = GeneratePromptDefinitionResponse(definition, null);
|
||||
AIProjectClient client = this.CreateTestAgentClient(agentName: "test-agent", agentDefinitionResponse: agentDefinitionResponse);
|
||||
using var testClient = CreateTestAgentClientWithHandler(agentName: "test-agent", agentDefinitionResponse: agentDefinitionResponse);
|
||||
|
||||
var options = new AgentVersionCreationOptions(definition);
|
||||
|
||||
// Act
|
||||
var agent = await client.CreateAIAgentAsync(
|
||||
var agent = await testClient.Client.CreateAIAgentAsync(
|
||||
"test-agent",
|
||||
options,
|
||||
clientFactory: (innerClient) => new TestChatClient(innerClient));
|
||||
@@ -1390,7 +1390,8 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
#region User-Agent Header Tests
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the user-agent header is added to both synchronous and asynchronous requests made by agent creation methods.
|
||||
/// Verifies that the MEAI user-agent header is added to CreateAIAgentAsync POST requests
|
||||
/// via the protocol method's RequestOptions pipeline policy.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task CreateAIAgentAsync_UserAgentHeaderAddedToRequestsAsync()
|
||||
@@ -1398,9 +1399,12 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
using var httpHandler = new HttpHandlerAssert(request =>
|
||||
{
|
||||
Assert.Equal("POST", request.Method.Method);
|
||||
Assert.Contains("MEAI", request.Headers.UserAgent.ToString());
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(TestDataUtil.GetAgentResponseJson(), Encoding.UTF8, "application/json") };
|
||||
// Verify MEAI user-agent header is present on CreateAgentVersion POST request
|
||||
Assert.True(request.Headers.TryGetValues("User-Agent", out var userAgentValues));
|
||||
Assert.Contains(userAgentValues, v => v.Contains("MEAI"));
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(TestDataUtil.GetAgentVersionResponseJson(), Encoding.UTF8, "application/json") };
|
||||
});
|
||||
|
||||
#pragma warning disable CA5399
|
||||
@@ -1940,7 +1944,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithTextResponseFormat_CreatesAgentSuccessfullyAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient();
|
||||
using var testClient = CreateTestAgentClientWithHandler();
|
||||
var options = new ChatClientAgentOptions
|
||||
{
|
||||
Name = "test-agent",
|
||||
@@ -1952,7 +1956,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
};
|
||||
|
||||
// Act
|
||||
ChatClientAgent agent = await client.CreateAIAgentAsync("test-model", options);
|
||||
ChatClientAgent agent = await testClient.Client.CreateAIAgentAsync("test-model", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -1966,7 +1970,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithJsonResponseFormatWithoutSchema_CreatesAgentSuccessfullyAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient();
|
||||
using var testClient = CreateTestAgentClientWithHandler();
|
||||
var options = new ChatClientAgentOptions
|
||||
{
|
||||
Name = "test-agent",
|
||||
@@ -1978,7 +1982,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
};
|
||||
|
||||
// Act
|
||||
ChatClientAgent agent = await client.CreateAIAgentAsync("test-model", options);
|
||||
ChatClientAgent agent = await testClient.Client.CreateAIAgentAsync("test-model", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -1992,7 +1996,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithJsonResponseFormatWithSchema_CreatesAgentSuccessfullyAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient();
|
||||
using var testClient = CreateTestAgentClientWithHandler();
|
||||
JsonElement schemaElement = AIJsonUtilities.CreateJsonSchema(typeof(TestSchema));
|
||||
var jsonFormat = ChatResponseFormat.ForJsonSchema(schemaElement, "test_schema", "A test schema");
|
||||
var options = new ChatClientAgentOptions
|
||||
@@ -2006,7 +2010,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
};
|
||||
|
||||
// Act
|
||||
ChatClientAgent agent = await client.CreateAIAgentAsync("test-model", options);
|
||||
ChatClientAgent agent = await testClient.Client.CreateAIAgentAsync("test-model", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -2020,7 +2024,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithJsonResponseFormatWithSchemaAndStrictMode_CreatesAgentSuccessfullyAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient();
|
||||
using var testClient = CreateTestAgentClientWithHandler();
|
||||
JsonElement schemaElement = AIJsonUtilities.CreateJsonSchema(typeof(TestSchema));
|
||||
var jsonFormat = ChatResponseFormat.ForJsonSchema(schemaElement, "test_schema", "A test schema");
|
||||
var additionalProps = new AdditionalPropertiesDictionary
|
||||
@@ -2039,7 +2043,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
};
|
||||
|
||||
// Act
|
||||
ChatClientAgent agent = await client.CreateAIAgentAsync("test-model", options);
|
||||
ChatClientAgent agent = await testClient.Client.CreateAIAgentAsync("test-model", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -2053,7 +2057,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithJsonResponseFormatWithSchemaAndStrictModeFalse_CreatesAgentSuccessfullyAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient();
|
||||
using var testClient = CreateTestAgentClientWithHandler();
|
||||
JsonElement schemaElement = AIJsonUtilities.CreateJsonSchema(typeof(TestSchema));
|
||||
var jsonFormat = ChatResponseFormat.ForJsonSchema(schemaElement, "test_schema", "A test schema");
|
||||
var additionalProps = new AdditionalPropertiesDictionary
|
||||
@@ -2072,7 +2076,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
};
|
||||
|
||||
// Act
|
||||
ChatClientAgent agent = await client.CreateAIAgentAsync("test-model", options);
|
||||
ChatClientAgent agent = await testClient.Client.CreateAIAgentAsync("test-model", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -2090,7 +2094,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithRawRepresentationFactory_CreatesAgentSuccessfullyAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient();
|
||||
using var testClient = CreateTestAgentClientWithHandler();
|
||||
var options = new ChatClientAgentOptions
|
||||
{
|
||||
Name = "test-agent",
|
||||
@@ -2102,7 +2106,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
};
|
||||
|
||||
// Act
|
||||
ChatClientAgent agent = await client.CreateAIAgentAsync("test-model", options);
|
||||
ChatClientAgent agent = await testClient.Client.CreateAIAgentAsync("test-model", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -2116,7 +2120,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithRawRepresentationFactoryReturningNull_CreatesAgentSuccessfullyAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient();
|
||||
using var testClient = CreateTestAgentClientWithHandler();
|
||||
var options = new ChatClientAgentOptions
|
||||
{
|
||||
Name = "test-agent",
|
||||
@@ -2128,7 +2132,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
};
|
||||
|
||||
// Act
|
||||
ChatClientAgent agent = await client.CreateAIAgentAsync("test-model", options);
|
||||
ChatClientAgent agent = await testClient.Client.CreateAIAgentAsync("test-model", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -2142,7 +2146,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithRawRepresentationFactoryReturningNonCreateResponseOptions_CreatesAgentSuccessfullyAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient();
|
||||
using var testClient = CreateTestAgentClientWithHandler();
|
||||
var options = new ChatClientAgentOptions
|
||||
{
|
||||
Name = "test-agent",
|
||||
@@ -2154,7 +2158,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
};
|
||||
|
||||
// Act
|
||||
ChatClientAgent agent = await client.CreateAIAgentAsync("test-model", options);
|
||||
ChatClientAgent agent = await testClient.Client.CreateAIAgentAsync("test-model", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -2172,7 +2176,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithDescription_SetsDescriptionAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient(description: "Test description");
|
||||
using var testClient = CreateTestAgentClientWithHandler(description: "Test description");
|
||||
var options = new ChatClientAgentOptions
|
||||
{
|
||||
Name = "test-agent",
|
||||
@@ -2181,7 +2185,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
};
|
||||
|
||||
// Act
|
||||
ChatClientAgent agent = await client.CreateAIAgentAsync("test-model", options);
|
||||
ChatClientAgent agent = await testClient.Client.CreateAIAgentAsync("test-model", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -2195,7 +2199,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithoutDescription_CreatesAgentSuccessfullyAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient();
|
||||
using var testClient = CreateTestAgentClientWithHandler();
|
||||
var options = new ChatClientAgentOptions
|
||||
{
|
||||
Name = "test-agent",
|
||||
@@ -2203,7 +2207,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
};
|
||||
|
||||
// Act
|
||||
ChatClientAgent agent = await client.CreateAIAgentAsync("test-model", options);
|
||||
ChatClientAgent agent = await testClient.Client.CreateAIAgentAsync("test-model", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -2624,7 +2628,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
public async Task CreateAIAgentAsync_WithHostedToolTypes_CreatesAgentSuccessfullyAsync()
|
||||
{
|
||||
// Arrange
|
||||
AIProjectClient client = this.CreateTestAgentClient();
|
||||
using var testClient = CreateTestAgentClientWithHandler();
|
||||
var webSearchTool = new HostedWebSearchTool();
|
||||
|
||||
var options = new ChatClientAgentOptions
|
||||
@@ -2638,7 +2642,7 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
};
|
||||
|
||||
// Act
|
||||
ChatClientAgent agent = await client.CreateAIAgentAsync("test-model", options);
|
||||
ChatClientAgent agent = await testClient.Client.CreateAIAgentAsync("test-model", options);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(agent);
|
||||
@@ -2791,6 +2795,54 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
return new FakeAgentClient(agentName, instructions, description, agentDefinitionResponse);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a test AIProjectClient backed by an HTTP handler that returns canned responses.
|
||||
/// Used for tests that exercise the protocol-method code path (CreateAgentVersion).
|
||||
/// The returned client must be disposed to clean up the underlying HttpClient/handler.
|
||||
/// </summary>
|
||||
private static DisposableTestClient CreateTestAgentClientWithHandler(string? agentName = null, string? instructions = null, string? description = null, AgentDefinition? agentDefinitionResponse = null)
|
||||
{
|
||||
var responseJson = TestDataUtil.GetAgentVersionResponseJson(agentName, agentDefinitionResponse, instructions, description);
|
||||
|
||||
var httpHandler = new HttpHandlerAssert(_ =>
|
||||
new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(responseJson, Encoding.UTF8, "application/json") });
|
||||
|
||||
#pragma warning disable CA5399
|
||||
var httpClient = new HttpClient(httpHandler);
|
||||
#pragma warning restore CA5399
|
||||
|
||||
var client = new AIProjectClient(
|
||||
new Uri("https://test.openai.azure.com/"),
|
||||
new FakeAuthenticationTokenProvider(),
|
||||
new() { Transport = new HttpClientPipelineTransport(httpClient) });
|
||||
|
||||
return new DisposableTestClient(client, httpClient, httpHandler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps an AIProjectClient and its disposable dependencies for deterministic cleanup.
|
||||
/// </summary>
|
||||
private sealed class DisposableTestClient : IDisposable
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly HttpHandlerAssert _httpHandler;
|
||||
|
||||
public DisposableTestClient(AIProjectClient client, HttpClient httpClient, HttpHandlerAssert httpHandler)
|
||||
{
|
||||
this.Client = client;
|
||||
this._httpClient = httpClient;
|
||||
this._httpHandler = httpHandler;
|
||||
}
|
||||
|
||||
public AIProjectClient Client { get; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this._httpClient.Dispose();
|
||||
this._httpHandler.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a test AgentRecord for testing.
|
||||
/// </summary>
|
||||
@@ -2975,25 +3027,13 @@ public sealed class AzureAIProjectChatClientExtensionsTests
|
||||
return Task.FromResult(ClientResult.FromValue(ModelReaderWriter.Read<AgentRecord>(BinaryData.FromString(responseJson))!, new MockPipelineResponse(200)));
|
||||
}
|
||||
|
||||
public override ClientResult CreateAgentVersion(string agentName, BinaryContent content, RequestOptions? options = null)
|
||||
{
|
||||
var responseJson = this.GetAgentVersionResponseJson();
|
||||
return ClientResult.FromValue(ModelReaderWriter.Read<AgentVersion>(BinaryData.FromString(responseJson))!, new MockPipelineResponse(200, BinaryData.FromString(responseJson)));
|
||||
}
|
||||
|
||||
public override ClientResult<AgentVersion> CreateAgentVersion(string agentName, AgentVersionCreationOptions? options = null, CancellationToken cancellationToken = default)
|
||||
public override ClientResult<AgentVersion> CreateAgentVersion(string agentName, AgentVersionCreationOptions options, BinaryData? foundryFeatures = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var responseJson = this.GetAgentVersionResponseJson();
|
||||
return ClientResult.FromValue(ModelReaderWriter.Read<AgentVersion>(BinaryData.FromString(responseJson))!, new MockPipelineResponse(200));
|
||||
}
|
||||
|
||||
public override Task<ClientResult> CreateAgentVersionAsync(string agentName, BinaryContent content, RequestOptions? options = null)
|
||||
{
|
||||
var responseJson = this.GetAgentVersionResponseJson();
|
||||
return Task.FromResult<ClientResult>(ClientResult.FromValue(ModelReaderWriter.Read<AgentVersion>(BinaryData.FromString(responseJson))!, new MockPipelineResponse(200, BinaryData.FromString(responseJson))));
|
||||
}
|
||||
|
||||
public override Task<ClientResult<AgentVersion>> CreateAgentVersionAsync(string agentName, AgentVersionCreationOptions? options = null, CancellationToken cancellationToken = default)
|
||||
public override Task<ClientResult<AgentVersion>> CreateAgentVersionAsync(string agentName, AgentVersionCreationOptions options, BinaryData? foundryFeatures = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var responseJson = this.GetAgentVersionResponseJson();
|
||||
return Task.FromResult(ClientResult.FromValue(ModelReaderWriter.Read<AgentVersion>(BinaryData.FromString(responseJson))!, new MockPipelineResponse(200)));
|
||||
|
||||
@@ -22,7 +22,7 @@ public class AzureAIProjectChatClientTests
|
||||
var requestTriggered = false;
|
||||
using var httpHandler = new HttpHandlerAssert(async (request) =>
|
||||
{
|
||||
if (request.RequestUri!.PathAndQuery.Contains("openai/responses"))
|
||||
if (request.Method == HttpMethod.Post && request.RequestUri!.PathAndQuery.Contains("/responses"))
|
||||
{
|
||||
requestTriggered = true;
|
||||
|
||||
@@ -71,7 +71,7 @@ public class AzureAIProjectChatClientTests
|
||||
var requestTriggered = false;
|
||||
using var httpHandler = new HttpHandlerAssert(async (request) =>
|
||||
{
|
||||
if (request.RequestUri!.PathAndQuery.Contains("openai/responses"))
|
||||
if (request.Method == HttpMethod.Post && request.RequestUri!.PathAndQuery.Contains("/responses"))
|
||||
{
|
||||
requestTriggered = true;
|
||||
|
||||
@@ -120,7 +120,7 @@ public class AzureAIProjectChatClientTests
|
||||
var requestTriggered = false;
|
||||
using var httpHandler = new HttpHandlerAssert(async (request) =>
|
||||
{
|
||||
if (request.RequestUri!.PathAndQuery.Contains("openai/responses"))
|
||||
if (request.Method == HttpMethod.Post && request.RequestUri!.PathAndQuery.Contains("/responses"))
|
||||
{
|
||||
requestTriggered = true;
|
||||
|
||||
@@ -169,7 +169,7 @@ public class AzureAIProjectChatClientTests
|
||||
var requestTriggered = false;
|
||||
using var httpHandler = new HttpHandlerAssert(async (request) =>
|
||||
{
|
||||
if (request.RequestUri!.PathAndQuery.Contains("openai/responses"))
|
||||
if (request.Method == HttpMethod.Post && request.RequestUri!.PathAndQuery.Contains("/responses"))
|
||||
{
|
||||
requestTriggered = true;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user