mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Merge branch 'main' into feature-xunit3-mtp-upgrade
This commit is contained in:
+9
-4
@@ -132,10 +132,15 @@ public class AzureAIAgentsPersistentCreateTests
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("CreateWithChatClientAgentOptionsAsync")]
|
||||
[InlineData("CreateWithFoundryOptionsAsync")]
|
||||
public async Task CreateAgent_CreatesAgentWithCodeInterpreterAsync(string createMechanism)
|
||||
[Fact]
|
||||
public Task CreateAgent_CreatesAgentWithCodeInterpreter_ChatClientAgentOptionsAsync()
|
||||
=> this.CreateAgent_CreatesAgentWithCodeInterpreterAsync("CreateWithChatClientAgentOptionsAsync");
|
||||
|
||||
[RetryFact(Constants.RetryCount, Constants.RetryDelay)]
|
||||
public Task CreateAgent_CreatesAgentWithCodeInterpreter_FoundryOptionsAsync()
|
||||
=> this.CreateAgent_CreatesAgentWithCodeInterpreterAsync("CreateWithFoundryOptionsAsync");
|
||||
|
||||
private async Task CreateAgent_CreatesAgentWithCodeInterpreterAsync(string createMechanism)
|
||||
{
|
||||
// Arrange.
|
||||
const string AgentInstructions = """
|
||||
|
||||
+6
-4
@@ -43,23 +43,25 @@ public class InMemoryChatHistoryProviderTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StateKey_ReturnsDefaultKey_WhenNoOptionsProvided()
|
||||
public void StateKeys_ReturnsDefaultKey_WhenNoOptionsProvided()
|
||||
{
|
||||
// Arrange & Act
|
||||
var provider = new InMemoryChatHistoryProvider();
|
||||
|
||||
// Assert
|
||||
Assert.Equal("InMemoryChatHistoryProvider", provider.StateKey);
|
||||
Assert.Single(provider.StateKeys);
|
||||
Assert.Contains("InMemoryChatHistoryProvider", provider.StateKeys);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StateKey_ReturnsCustomKey_WhenSetViaOptions()
|
||||
public void StateKeys_ReturnsCustomKey_WhenSetViaOptions()
|
||||
{
|
||||
// Arrange & Act
|
||||
var provider = new InMemoryChatHistoryProvider(new() { StateKey = "custom-key" });
|
||||
|
||||
// Assert
|
||||
Assert.Equal("custom-key", provider.StateKey);
|
||||
Assert.Single(provider.StateKeys);
|
||||
Assert.Contains("custom-key", provider.StateKeys);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
+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);
|
||||
@@ -2688,7 +2692,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
|
||||
@@ -2702,7 +2706,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);
|
||||
@@ -2855,6 +2859,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>
|
||||
@@ -3039,25 +3091,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 = null, string? 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 = null, string? 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;
|
||||
|
||||
|
||||
+6
-4
@@ -152,7 +152,7 @@ public sealed class CosmosChatHistoryProviderTests : IAsyncLifetime, IDisposable
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", "CosmosDB")]
|
||||
public void StateKey_ReturnsDefaultKey_WhenNoStateKeyProvided()
|
||||
public void StateKeys_ReturnsDefaultKey_WhenNoStateKeyProvided()
|
||||
{
|
||||
// Arrange & Act
|
||||
this.SkipIfEmulatorNotAvailable();
|
||||
@@ -161,12 +161,13 @@ public sealed class CosmosChatHistoryProviderTests : IAsyncLifetime, IDisposable
|
||||
_ => new CosmosChatHistoryProvider.State("test-conversation"));
|
||||
|
||||
// Assert
|
||||
Assert.Equal("CosmosChatHistoryProvider", provider.StateKey);
|
||||
Assert.Single(provider.StateKeys);
|
||||
Assert.Contains("CosmosChatHistoryProvider", provider.StateKeys);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", "CosmosDB")]
|
||||
public void StateKey_ReturnsCustomKey_WhenSetViaConstructor()
|
||||
public void StateKeys_ReturnsCustomKey_WhenSetViaConstructor()
|
||||
{
|
||||
// Arrange & Act
|
||||
this.SkipIfEmulatorNotAvailable();
|
||||
@@ -176,7 +177,8 @@ public sealed class CosmosChatHistoryProviderTests : IAsyncLifetime, IDisposable
|
||||
stateKey: "custom-key");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("custom-key", provider.StateKey);
|
||||
Assert.Single(provider.StateKeys);
|
||||
Assert.Contains("custom-key", provider.StateKeys);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
+2
-2
@@ -109,7 +109,7 @@ public sealed class GitHubCopilotAgentTests
|
||||
var hooks = new SessionHooks();
|
||||
var infiniteSessions = new InfiniteSessionConfig();
|
||||
var systemMessage = new SystemMessageConfig { Mode = SystemMessageMode.Append, Content = "Be helpful" };
|
||||
PermissionHandler permissionHandler = (_, _) => Task.FromResult(new PermissionRequestResult());
|
||||
PermissionRequestHandler permissionHandler = (_, _) => Task.FromResult(new PermissionRequestResult());
|
||||
UserInputHandler userInputHandler = (_, _) => Task.FromResult(new UserInputResponse { Answer = "input" });
|
||||
var mcpServers = new Dictionary<string, object> { ["server1"] = new McpLocalServerConfig() };
|
||||
|
||||
@@ -160,7 +160,7 @@ public sealed class GitHubCopilotAgentTests
|
||||
var hooks = new SessionHooks();
|
||||
var infiniteSessions = new InfiniteSessionConfig();
|
||||
var systemMessage = new SystemMessageConfig { Mode = SystemMessageMode.Append, Content = "Be helpful" };
|
||||
PermissionHandler permissionHandler = (_, _) => Task.FromResult(new PermissionRequestResult());
|
||||
PermissionRequestHandler permissionHandler = (_, _) => Task.FromResult(new PermissionRequestResult());
|
||||
UserInputHandler userInputHandler = (_, _) => Task.FromResult(new UserInputResponse { Answer = "input" });
|
||||
var mcpServers = new Dictionary<string, object> { ["server1"] = new McpLocalServerConfig() };
|
||||
|
||||
|
||||
@@ -67,17 +67,18 @@ public sealed class Mem0ProviderTests : IDisposable
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StateKey_ReturnsDefaultKey_WhenNoOptionsProvided()
|
||||
public void StateKeys_ReturnsDefaultKey_WhenNoOptionsProvided()
|
||||
{
|
||||
// Arrange & Act
|
||||
var provider = new Mem0Provider(this._httpClient, _ => new Mem0Provider.State(new Mem0ProviderScope { ThreadId = "tid" }));
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Mem0Provider", provider.StateKey);
|
||||
Assert.Single(provider.StateKeys);
|
||||
Assert.Contains("Mem0Provider", provider.StateKeys);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StateKey_ReturnsCustomKey_WhenSetViaOptions()
|
||||
public void StateKeys_ReturnsCustomKey_WhenSetViaOptions()
|
||||
{
|
||||
// Arrange & Act
|
||||
var provider = new Mem0Provider(
|
||||
@@ -86,7 +87,8 @@ public sealed class Mem0ProviderTests : IDisposable
|
||||
new Mem0ProviderOptions { StateKey = "custom-key" });
|
||||
|
||||
// Assert
|
||||
Assert.Equal("custom-key", provider.StateKey);
|
||||
Assert.Single(provider.StateKeys);
|
||||
Assert.Contains("custom-key", provider.StateKeys);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -419,7 +421,7 @@ public sealed class Mem0ProviderTests : IDisposable
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task StateKey_CanBeConfiguredViaOptionsAsync()
|
||||
public async Task StateKeys_CanBeConfiguredViaOptionsAsync()
|
||||
{
|
||||
// Arrange
|
||||
this._handler.EnqueueJsonResponse("[]");
|
||||
|
||||
+3
-3
@@ -380,7 +380,7 @@ public class AIContextProviderChatClientTests
|
||||
/// </summary>
|
||||
private sealed class TestAIContextProvider : AIContextProvider
|
||||
{
|
||||
private readonly string _stateKey;
|
||||
private readonly IReadOnlyList<string> _stateKeys;
|
||||
private readonly IEnumerable<ChatMessage> _provideMessages;
|
||||
private readonly string? _provideInstructions;
|
||||
private readonly IEnumerable<AITool>? _provideTools;
|
||||
@@ -389,7 +389,7 @@ public class AIContextProviderChatClientTests
|
||||
|
||||
public InvokedContext? LastInvokedContext { get; private set; }
|
||||
|
||||
public override string StateKey => this._stateKey;
|
||||
public override IReadOnlyList<string> StateKeys => this._stateKeys;
|
||||
|
||||
public TestAIContextProvider(
|
||||
string stateKey,
|
||||
@@ -397,7 +397,7 @@ public class AIContextProviderChatClientTests
|
||||
string? provideInstructions = null,
|
||||
IEnumerable<AITool>? provideTools = null)
|
||||
{
|
||||
this._stateKey = stateKey;
|
||||
this._stateKeys = [stateKey];
|
||||
this._provideMessages = provideMessages ?? [];
|
||||
this._provideInstructions = provideInstructions;
|
||||
this._provideTools = provideTools;
|
||||
|
||||
@@ -105,8 +105,8 @@ public partial class ChatClientAgentTests
|
||||
ChatHistoryProvider = historyProvider
|
||||
}));
|
||||
|
||||
Assert.Contains("SharedKey", ex.Message);
|
||||
Assert.Contains(nameof(ChatHistoryProvider), ex.Message);
|
||||
Assert.Contains("ChatHistoryProvider", ex.Message);
|
||||
Assert.Contains("state key 'SharedKey'", ex.Message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -159,11 +159,11 @@ public partial class ChatClientAgentTests
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||
agent.RunAsync([new(ChatRole.User, "test")], session, options: new AgentRunOptions { AdditionalProperties = additionalProperties }));
|
||||
|
||||
Assert.Contains("SharedKey", ex.Message);
|
||||
Assert.Contains("state key 'SharedKey'", ex.Message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that RunAsync succeeds when an override ChatHistoryProvider uses the same StateKey as the default ChatHistoryProvider.
|
||||
/// Verify that RunAsync succeeds when an override ChatHistoryProvider uses the same StateKeys as the default ChatHistoryProvider.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task RunAsync_SucceedsWhenOverrideChatHistoryProviderSharesKeyWithDefaultAsync()
|
||||
@@ -192,6 +192,102 @@ public partial class ChatClientAgentTests
|
||||
await agent.RunAsync([new(ChatRole.User, "test")], session, options: new AgentRunOptions { AdditionalProperties = additionalProperties });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that the constructor throws when two multi-key AIContextProviders have an overlapping key.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Constructor_ThrowsWhenMultiKeyAIContextProvidersOverlap()
|
||||
{
|
||||
// Arrange
|
||||
var chatClient = new Mock<IChatClient>().Object;
|
||||
var provider1 = new MultiKeyTestAIContextProvider("Key1", "SharedKey");
|
||||
var provider2 = new MultiKeyTestAIContextProvider("Key2", "SharedKey");
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<InvalidOperationException>(() =>
|
||||
new ChatClientAgent(chatClient, options: new()
|
||||
{
|
||||
AIContextProviders = [provider1, provider2]
|
||||
}));
|
||||
|
||||
Assert.Contains("state key 'SharedKey'", ex.Message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that the constructor throws when a multi-key ChatHistoryProvider has an overlapping key with an AIContextProvider.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Constructor_ThrowsWhenMultiKeyChatHistoryProviderOverlapsWithAIContextProvider()
|
||||
{
|
||||
// Arrange
|
||||
var chatClient = new Mock<IChatClient>().Object;
|
||||
var contextProvider = new MultiKeyTestAIContextProvider("Key1", "SharedKey");
|
||||
var historyProvider = new MultiKeyTestChatHistoryProvider("Key2", "SharedKey");
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<InvalidOperationException>(() =>
|
||||
new ChatClientAgent(chatClient, options: new()
|
||||
{
|
||||
AIContextProviders = [contextProvider],
|
||||
ChatHistoryProvider = historyProvider
|
||||
}));
|
||||
|
||||
Assert.Contains("state key 'SharedKey'", ex.Message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that the constructor succeeds when multi-key providers have no overlapping keys.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Constructor_SucceedsWithMultiKeyProvidersWithUniqueKeys()
|
||||
{
|
||||
// Arrange
|
||||
var chatClient = new Mock<IChatClient>().Object;
|
||||
var contextProvider1 = new MultiKeyTestAIContextProvider("Key1", "Key2");
|
||||
var contextProvider2 = new MultiKeyTestAIContextProvider("Key3", "Key4");
|
||||
var historyProvider = new MultiKeyTestChatHistoryProvider("Key5", "Key6");
|
||||
|
||||
// Act & Assert - should not throw
|
||||
_ = new ChatClientAgent(chatClient, options: new()
|
||||
{
|
||||
AIContextProviders = [contextProvider1, contextProvider2],
|
||||
ChatHistoryProvider = historyProvider
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that RunAsync throws when a multi-key override ChatHistoryProvider has an overlapping key with an AIContextProvider.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task RunAsync_ThrowsWhenMultiKeyOverrideChatHistoryProviderClashesWithAIContextProviderAsync()
|
||||
{
|
||||
// Arrange
|
||||
Mock<IChatClient> mockService = new();
|
||||
mockService.Setup(
|
||||
s => s.GetResponseAsync(
|
||||
It.IsAny<IEnumerable<ChatMessage>>(),
|
||||
It.IsAny<ChatOptions>(),
|
||||
It.IsAny<CancellationToken>())).ReturnsAsync(new ChatResponse([new(ChatRole.Assistant, "response")]));
|
||||
|
||||
var contextProvider = new MultiKeyTestAIContextProvider("Key1", "SharedKey");
|
||||
var overrideHistoryProvider = new MultiKeyTestChatHistoryProvider("Key2", "SharedKey");
|
||||
|
||||
ChatClientAgent agent = new(mockService.Object, options: new()
|
||||
{
|
||||
AIContextProviders = [contextProvider]
|
||||
});
|
||||
|
||||
// Act & Assert
|
||||
ChatClientAgentSession? session = await agent.CreateSessionAsync() as ChatClientAgentSession;
|
||||
AdditionalPropertiesDictionary additionalProperties = new();
|
||||
additionalProperties.Add<ChatHistoryProvider>(overrideHistoryProvider);
|
||||
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||
agent.RunAsync([new(ChatRole.User, "test")], session, options: new AgentRunOptions { AdditionalProperties = additionalProperties }));
|
||||
|
||||
Assert.Contains("state key 'SharedKey'", ex.Message);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region RunAsync Tests
|
||||
@@ -489,6 +585,7 @@ public partial class ChatClientAgentTests
|
||||
.ReturnsAsync(new ChatResponse(responseMessages));
|
||||
|
||||
var mockProvider = new Mock<AIContextProvider>(null, null, null);
|
||||
mockProvider.SetupGet(p => p.StateKeys).Returns(["TestProvider"]);
|
||||
mockProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask<AIContext>>("InvokingCoreAsync", ItExpr.IsAny<AIContextProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -560,6 +657,7 @@ public partial class ChatClientAgentTests
|
||||
.Throws(new InvalidOperationException("downstream failure"));
|
||||
|
||||
var mockProvider = new Mock<AIContextProvider>(null, null, null);
|
||||
mockProvider.SetupGet(p => p.StateKeys).Returns(["TestProvider"]);
|
||||
mockProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask<AIContext>>("InvokingCoreAsync", ItExpr.IsAny<AIContextProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -618,6 +716,7 @@ public partial class ChatClientAgentTests
|
||||
.ReturnsAsync(new ChatResponse([new(ChatRole.Assistant, "response")]));
|
||||
|
||||
var mockProvider = new Mock<AIContextProvider>(null, null, null);
|
||||
mockProvider.SetupGet(p => p.StateKeys).Returns(["TestProvider"]);
|
||||
mockProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask<AIContext>>("InvokingCoreAsync", ItExpr.IsAny<AIContextProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -678,7 +777,7 @@ public partial class ChatClientAgentTests
|
||||
|
||||
// Provider 1: adds a system message and a tool
|
||||
var mockProvider1 = new Mock<AIContextProvider>(null, null, null);
|
||||
mockProvider1.SetupGet(p => p.StateKey).Returns("Provider1");
|
||||
mockProvider1.SetupGet(p => p.StateKeys).Returns(["Provider1"]);
|
||||
mockProvider1
|
||||
.Protected()
|
||||
.Setup<ValueTask<AIContext>>("InvokingCoreAsync", ItExpr.IsAny<AIContextProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -697,7 +796,7 @@ public partial class ChatClientAgentTests
|
||||
// Provider 2: adds another system message and verifies it receives accumulated context from provider 1
|
||||
AIContext? provider2ReceivedContext = null;
|
||||
var mockProvider2 = new Mock<AIContextProvider>(null, null, null);
|
||||
mockProvider2.SetupGet(p => p.StateKey).Returns("Provider2");
|
||||
mockProvider2.SetupGet(p => p.StateKeys).Returns(["Provider2"]);
|
||||
mockProvider2
|
||||
.Protected()
|
||||
.Setup<ValueTask<AIContext>>("InvokingCoreAsync", ItExpr.IsAny<AIContextProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -785,7 +884,7 @@ public partial class ChatClientAgentTests
|
||||
.ThrowsAsync(new InvalidOperationException("downstream failure"));
|
||||
|
||||
var mockProvider1 = new Mock<AIContextProvider>(null, null, null);
|
||||
mockProvider1.SetupGet(p => p.StateKey).Returns("Provider1");
|
||||
mockProvider1.SetupGet(p => p.StateKeys).Returns(["Provider1"]);
|
||||
mockProvider1
|
||||
.Protected()
|
||||
.Setup<ValueTask<AIContext>>("InvokingCoreAsync", ItExpr.IsAny<AIContextProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -802,7 +901,7 @@ public partial class ChatClientAgentTests
|
||||
.Returns(new ValueTask());
|
||||
|
||||
var mockProvider2 = new Mock<AIContextProvider>(null, null, null);
|
||||
mockProvider2.SetupGet(p => p.StateKey).Returns("Provider2");
|
||||
mockProvider2.SetupGet(p => p.StateKeys).Returns(["Provider2"]);
|
||||
mockProvider2
|
||||
.Protected()
|
||||
.Setup<ValueTask<AIContext>>("InvokingCoreAsync", ItExpr.IsAny<AIContextProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -870,7 +969,7 @@ public partial class ChatClientAgentTests
|
||||
.Returns(ToAsyncEnumerableAsync(responseUpdates));
|
||||
|
||||
var mockProvider1 = new Mock<AIContextProvider>(null, null, null);
|
||||
mockProvider1.SetupGet(p => p.StateKey).Returns("Provider1");
|
||||
mockProvider1.SetupGet(p => p.StateKeys).Returns(["Provider1"]);
|
||||
mockProvider1
|
||||
.Protected()
|
||||
.Setup<ValueTask<AIContext>>("InvokingCoreAsync", ItExpr.IsAny<AIContextProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -887,7 +986,7 @@ public partial class ChatClientAgentTests
|
||||
.Returns(new ValueTask());
|
||||
|
||||
var mockProvider2 = new Mock<AIContextProvider>(null, null, null);
|
||||
mockProvider2.SetupGet(p => p.StateKey).Returns("Provider2");
|
||||
mockProvider2.SetupGet(p => p.StateKeys).Returns(["Provider2"]);
|
||||
mockProvider2
|
||||
.Protected()
|
||||
.Setup<ValueTask<AIContext>>("InvokingCoreAsync", ItExpr.IsAny<AIContextProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -1829,6 +1928,7 @@ public partial class ChatClientAgentTests
|
||||
.Returns(ToAsyncEnumerableAsync(responseUpdates));
|
||||
|
||||
var mockProvider = new Mock<AIContextProvider>(null, null, null);
|
||||
mockProvider.SetupGet(p => p.StateKeys).Returns(["TestProvider"]);
|
||||
mockProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask<AIContext>>("InvokingCoreAsync", ItExpr.IsAny<AIContextProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -1908,6 +2008,7 @@ public partial class ChatClientAgentTests
|
||||
.Throws(new InvalidOperationException("downstream failure"));
|
||||
|
||||
var mockProvider = new Mock<AIContextProvider>(null, null, null);
|
||||
mockProvider.SetupGet(p => p.StateKeys).Returns(["TestProvider"]);
|
||||
mockProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask<AIContext>>("InvokingCoreAsync", ItExpr.IsAny<AIContextProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -1965,7 +2066,17 @@ public partial class ChatClientAgentTests
|
||||
|
||||
private sealed class TestAIContextProvider(string stateKey) : AIContextProvider
|
||||
{
|
||||
public override string StateKey => stateKey;
|
||||
private readonly IReadOnlyList<string> _stateKeys = [stateKey];
|
||||
|
||||
public override IReadOnlyList<string> StateKeys => this._stateKeys;
|
||||
|
||||
protected override ValueTask<AIContext> InvokingCoreAsync(InvokingContext context, CancellationToken cancellationToken = default)
|
||||
=> new(context.AIContext);
|
||||
}
|
||||
|
||||
private sealed class MultiKeyTestAIContextProvider(params string[] stateKeys) : AIContextProvider
|
||||
{
|
||||
public override IReadOnlyList<string> StateKeys => stateKeys;
|
||||
|
||||
protected override ValueTask<AIContext> InvokingCoreAsync(InvokingContext context, CancellationToken cancellationToken = default)
|
||||
=> new(context.AIContext);
|
||||
@@ -1973,7 +2084,20 @@ public partial class ChatClientAgentTests
|
||||
|
||||
private sealed class TestChatHistoryProvider(string stateKey) : ChatHistoryProvider
|
||||
{
|
||||
public override string StateKey => stateKey;
|
||||
private readonly IReadOnlyList<string> _stateKeys = [stateKey];
|
||||
|
||||
public override IReadOnlyList<string> StateKeys => this._stateKeys;
|
||||
|
||||
protected override ValueTask<IEnumerable<ChatMessage>> InvokingCoreAsync(InvokingContext context, CancellationToken cancellationToken = default)
|
||||
=> new(context.RequestMessages);
|
||||
|
||||
protected override ValueTask InvokedCoreAsync(InvokedContext context, CancellationToken cancellationToken = default)
|
||||
=> default;
|
||||
}
|
||||
|
||||
private sealed class MultiKeyTestChatHistoryProvider(params string[] stateKeys) : ChatHistoryProvider
|
||||
{
|
||||
public override IReadOnlyList<string> StateKeys => stateKeys;
|
||||
|
||||
protected override ValueTask<IEnumerable<ChatMessage>> InvokingCoreAsync(InvokingContext context, CancellationToken cancellationToken = default)
|
||||
=> new(context.RequestMessages);
|
||||
|
||||
+8
-8
@@ -339,7 +339,7 @@ public class ChatClientAgent_BackgroundResponsesTests
|
||||
|
||||
// Create a mock chat history provider that would normally provide messages
|
||||
var mockChatHistoryProvider = new Mock<ChatHistoryProvider>(null, null, null);
|
||||
mockChatHistoryProvider.SetupGet(p => p.StateKey).Returns("ChatHistoryProvider");
|
||||
mockChatHistoryProvider.SetupGet(p => p.StateKeys).Returns(["ChatHistoryProvider"]);
|
||||
mockChatHistoryProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask<IEnumerable<ChatMessage>>>("InvokingCoreAsync", ItExpr.IsAny<ChatHistoryProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -347,7 +347,7 @@ public class ChatClientAgent_BackgroundResponsesTests
|
||||
|
||||
// Create a mock AI context provider that would normally provide context
|
||||
var mockContextProvider = new Mock<AIContextProvider>(null, null, null);
|
||||
mockContextProvider.SetupGet(p => p.StateKey).Returns("Provider1");
|
||||
mockContextProvider.SetupGet(p => p.StateKeys).Returns(["Provider1"]);
|
||||
mockContextProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask<AIContext>>("InvokingCoreAsync", ItExpr.IsAny<AIContextProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -408,7 +408,7 @@ public class ChatClientAgent_BackgroundResponsesTests
|
||||
|
||||
// Create a mock chat history provider that would normally provide messages
|
||||
var mockChatHistoryProvider = new Mock<ChatHistoryProvider>(null, null, null);
|
||||
mockChatHistoryProvider.SetupGet(p => p.StateKey).Returns("ChatHistoryProvider");
|
||||
mockChatHistoryProvider.SetupGet(p => p.StateKeys).Returns(["ChatHistoryProvider"]);
|
||||
mockChatHistoryProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask<IEnumerable<ChatMessage>>>("InvokingCoreAsync", ItExpr.IsAny<ChatHistoryProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -416,7 +416,7 @@ public class ChatClientAgent_BackgroundResponsesTests
|
||||
|
||||
// Create a mock AI context provider that would normally provide context
|
||||
var mockContextProvider = new Mock<AIContextProvider>(null, null, null);
|
||||
mockContextProvider.SetupGet(p => p.StateKey).Returns("Provider1");
|
||||
mockContextProvider.SetupGet(p => p.StateKeys).Returns(["Provider1"]);
|
||||
mockContextProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask<AIContext>>("InvokingCoreAsync", ItExpr.IsAny<AIContextProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -639,7 +639,7 @@ public class ChatClientAgent_BackgroundResponsesTests
|
||||
|
||||
List<ChatMessage> capturedMessagesAddedToProvider = [];
|
||||
var mockChatHistoryProvider = new Mock<ChatHistoryProvider>(null, null, null);
|
||||
mockChatHistoryProvider.SetupGet(p => p.StateKey).Returns("ChatHistoryProvider");
|
||||
mockChatHistoryProvider.SetupGet(p => p.StateKeys).Returns(["ChatHistoryProvider"]);
|
||||
mockChatHistoryProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask>("InvokedCoreAsync", ItExpr.IsAny<ChatHistoryProvider.InvokedContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -648,7 +648,7 @@ public class ChatClientAgent_BackgroundResponsesTests
|
||||
|
||||
AIContextProvider.InvokedContext? capturedInvokedContext = null;
|
||||
var mockContextProvider = new Mock<AIContextProvider>(null, null, null);
|
||||
mockContextProvider.SetupGet(p => p.StateKey).Returns("Provider1");
|
||||
mockContextProvider.SetupGet(p => p.StateKeys).Returns(["Provider1"]);
|
||||
mockContextProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask>("InvokedCoreAsync", ItExpr.IsAny<AIContextProvider.InvokedContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -703,7 +703,7 @@ public class ChatClientAgent_BackgroundResponsesTests
|
||||
|
||||
List<ChatMessage> capturedMessagesAddedToProvider = [];
|
||||
var mockChatHistoryProvider = new Mock<ChatHistoryProvider>(null, null, null);
|
||||
mockChatHistoryProvider.SetupGet(p => p.StateKey).Returns("ChatHistoryProvider");
|
||||
mockChatHistoryProvider.SetupGet(p => p.StateKeys).Returns(["ChatHistoryProvider"]);
|
||||
mockChatHistoryProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask>("InvokedCoreAsync", ItExpr.IsAny<ChatHistoryProvider.InvokedContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -712,7 +712,7 @@ public class ChatClientAgent_BackgroundResponsesTests
|
||||
|
||||
AIContextProvider.InvokedContext? capturedInvokedContext = null;
|
||||
var mockContextProvider = new Mock<AIContextProvider>(null, null, null);
|
||||
mockContextProvider.SetupGet(p => p.StateKey).Returns("Provider1");
|
||||
mockContextProvider.SetupGet(p => p.StateKeys).Returns(["Provider1"]);
|
||||
mockContextProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask>("InvokedCoreAsync", ItExpr.IsAny<AIContextProvider.InvokedContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
|
||||
+4
@@ -186,6 +186,7 @@ public class ChatClientAgent_ChatHistoryManagementTests
|
||||
It.IsAny<CancellationToken>())).ReturnsAsync(new ChatResponse([new(ChatRole.Assistant, "response")]));
|
||||
|
||||
Mock<ChatHistoryProvider> mockChatHistoryProvider = new(null, null, null);
|
||||
mockChatHistoryProvider.SetupGet(p => p.StateKeys).Returns(["TestChatHistoryProvider"]);
|
||||
mockChatHistoryProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask<IEnumerable<ChatMessage>>>("InvokingCoreAsync", ItExpr.IsAny<ChatHistoryProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -241,6 +242,7 @@ public class ChatClientAgent_ChatHistoryManagementTests
|
||||
It.IsAny<CancellationToken>())).Throws(new InvalidOperationException("Test Error"));
|
||||
|
||||
Mock<ChatHistoryProvider> mockChatHistoryProvider = new(null, null, null);
|
||||
mockChatHistoryProvider.SetupGet(p => p.StateKeys).Returns(["TestChatHistoryProvider"]);
|
||||
mockChatHistoryProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask<IEnumerable<ChatMessage>>>("InvokingCoreAsync", ItExpr.IsAny<ChatHistoryProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -430,6 +432,7 @@ public class ChatClientAgent_ChatHistoryManagementTests
|
||||
|
||||
// Arrange a chat history provider to override the factory provided one.
|
||||
Mock<ChatHistoryProvider> mockOverrideChatHistoryProvider = new(null, null, null);
|
||||
mockOverrideChatHistoryProvider.SetupGet(p => p.StateKeys).Returns(["TestChatHistoryProvider"]);
|
||||
mockOverrideChatHistoryProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask<IEnumerable<ChatMessage>>>("InvokingCoreAsync", ItExpr.IsAny<ChatHistoryProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
@@ -443,6 +446,7 @@ public class ChatClientAgent_ChatHistoryManagementTests
|
||||
// Arrange a chat history provider to provide to the agent at construction time.
|
||||
// This one shouldn't be used since it is being overridden.
|
||||
Mock<ChatHistoryProvider> mockAgentOptionsChatHistoryProvider = new(null, null, null);
|
||||
mockAgentOptionsChatHistoryProvider.SetupGet(p => p.StateKeys).Returns(["TestChatHistoryProvider"]);
|
||||
mockAgentOptionsChatHistoryProvider
|
||||
.Protected()
|
||||
.Setup<ValueTask<IEnumerable<ChatMessage>>>("InvokingCoreAsync", ItExpr.IsAny<ChatHistoryProvider.InvokingContext>(), ItExpr.IsAny<CancellationToken>())
|
||||
|
||||
@@ -39,17 +39,18 @@ public sealed class TextSearchProviderTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StateKey_ReturnsDefaultKey_WhenNoOptionsProvided()
|
||||
public void StateKeys_ReturnsDefaultKey_WhenNoOptionsProvided()
|
||||
{
|
||||
// Arrange & Act
|
||||
var provider = new TextSearchProvider((_, _) => Task.FromResult<IEnumerable<TextSearchProvider.TextSearchResult>>([]));
|
||||
|
||||
// Assert
|
||||
Assert.Equal("TextSearchProvider", provider.StateKey);
|
||||
Assert.Single(provider.StateKeys);
|
||||
Assert.Contains("TextSearchProvider", provider.StateKeys);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StateKey_ReturnsCustomKey_WhenSetViaOptions()
|
||||
public void StateKeys_ReturnsCustomKey_WhenSetViaOptions()
|
||||
{
|
||||
// Arrange & Act
|
||||
var provider = new TextSearchProvider(
|
||||
@@ -57,7 +58,8 @@ public sealed class TextSearchProviderTests
|
||||
new TextSearchProviderOptions { StateKey = "custom-key" });
|
||||
|
||||
// Assert
|
||||
Assert.Equal("custom-key", provider.StateKey);
|
||||
Assert.Single(provider.StateKeys);
|
||||
Assert.Contains("custom-key", provider.StateKeys);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
||||
@@ -56,7 +56,7 @@ public class ChatHistoryMemoryProviderTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StateKey_ReturnsDefaultKey_WhenNoOptionsProvided()
|
||||
public void StateKeys_ReturnsDefaultKey_WhenNoOptionsProvided()
|
||||
{
|
||||
// Arrange & Act
|
||||
var provider = new ChatHistoryMemoryProvider(
|
||||
@@ -66,11 +66,12 @@ public class ChatHistoryMemoryProviderTests
|
||||
_ => new ChatHistoryMemoryProvider.State(new ChatHistoryMemoryProviderScope { UserId = "UID" }));
|
||||
|
||||
// Assert
|
||||
Assert.Equal("ChatHistoryMemoryProvider", provider.StateKey);
|
||||
Assert.Single(provider.StateKeys);
|
||||
Assert.Contains("ChatHistoryMemoryProvider", provider.StateKeys);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StateKey_ReturnsCustomKey_WhenSetViaOptions()
|
||||
public void StateKeys_ReturnsCustomKey_WhenSetViaOptions()
|
||||
{
|
||||
// Arrange & Act
|
||||
var provider = new ChatHistoryMemoryProvider(
|
||||
@@ -81,7 +82,8 @@ public class ChatHistoryMemoryProviderTests
|
||||
new ChatHistoryMemoryProviderOptions { StateKey = "custom-key" });
|
||||
|
||||
// Assert
|
||||
Assert.Equal("custom-key", provider.StateKey);
|
||||
Assert.Single(provider.StateKeys);
|
||||
Assert.Contains("custom-key", provider.StateKeys);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests;
|
||||
public sealed class DeclarativeCodeGenTest(ITestOutputHelper output) : WorkflowTest(output)
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("CheckSystem.yaml", "CheckSystem.json")]
|
||||
[InlineData("CheckSystem.yaml", "CheckSystem.json", Skip = "Temporarily skipped")]
|
||||
[InlineData("SendActivity.yaml", "SendActivity.json")]
|
||||
[InlineData("InvokeAgent.yaml", "InvokeAgent.json")]
|
||||
[InlineData("InvokeAgent.yaml", "InvokeAgent.json", true)]
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ namespace Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests;
|
||||
public sealed class DeclarativeWorkflowTest(ITestOutputHelper output) : WorkflowTest(output)
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("CheckSystem.yaml", "CheckSystem.json")]
|
||||
[InlineData("CheckSystem.yaml", "CheckSystem.json", Skip = "Temporarily skipped")]
|
||||
[InlineData("ConversationMessages.yaml", "ConversationMessages.json")]
|
||||
[InlineData("ConversationMessages.yaml", "ConversationMessages.json", true)]
|
||||
[InlineData("InputArguments.yaml", "InputArguments.json")]
|
||||
@@ -33,7 +33,7 @@ public sealed class DeclarativeWorkflowTest(ITestOutputHelper output) : Workflow
|
||||
public Task ValidateScenarioAsync(string workflowFileName, string testcaseFileName, bool externalConveration = false) =>
|
||||
this.RunWorkflowAsync(GetWorkflowPath(workflowFileName, isSample: true), testcaseFileName, externalConveration);
|
||||
|
||||
[Theory]
|
||||
[Theory(Skip = "Multi-turn tests hang in CI - needs investigation")]
|
||||
[InlineData("ConfirmInput.yaml", "ConfirmInput.json", false)]
|
||||
[InlineData("RequestExternalInput.yaml", "RequestExternalInput.json", false)]
|
||||
public Task ValidateMultiTurnAsync(string workflowFileName, string testcaseFileName, bool isSample) =>
|
||||
|
||||
+14
@@ -1,9 +1,23 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using AgentConformance.IntegrationTests;
|
||||
|
||||
namespace OpenAIAssistant.IntegrationTests;
|
||||
|
||||
public class OpenAIAssistantStructuredOutputRunTests() : StructuredOutputRunTests<OpenAIAssistantFixture>(() => new())
|
||||
{
|
||||
private const string SkipReason = "Fails intermittently on the build agent/CI";
|
||||
|
||||
[Fact(Skip = SkipReason)]
|
||||
public override Task RunWithResponseFormatReturnsExpectedResultAsync() =>
|
||||
base.RunWithResponseFormatReturnsExpectedResultAsync();
|
||||
|
||||
[Fact(Skip = SkipReason)]
|
||||
public override Task RunWithGenericTypeReturnsExpectedResultAsync() =>
|
||||
base.RunWithGenericTypeReturnsExpectedResultAsync();
|
||||
|
||||
[Fact(Skip = SkipReason)]
|
||||
public override Task RunWithPrimitiveTypeReturnsExpectedResultAsync() =>
|
||||
base.RunWithPrimitiveTypeReturnsExpectedResultAsync();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user