.NET: Duplicate System Instruction when creating a ChatClientAgentOptions instance with the constructor (#1382)

* unit test for using create agent option by constructor

* remove this for prevent duplicate when ChatClientAgentOption and ChatOption has same Instruction

* update unit test for ChatClientAgentOptions
This commit is contained in:
Trung Hieu
2025-10-16 16:24:00 +07:00
committed by GitHub
Unverified
parent db7f767180
commit 9677899600
3 changed files with 35 additions and 12 deletions
@@ -44,11 +44,6 @@ public class ChatClientAgentOptions
{
(this.ChatOptions ??= new()).Tools = tools;
}
if (instructions is not null)
{
(this.ChatOptions ??= new()).Instructions = instructions;
}
}
/// <summary>
@@ -61,9 +61,7 @@ public class ChatClientAgentOptionsTests
Assert.Null(options.Name);
Assert.Equal(Instructions, options.Instructions);
Assert.Null(options.Description);
Assert.NotNull(options.ChatOptions);
Assert.Equal(Instructions, options.ChatOptions.Instructions);
Assert.Null(options.ChatOptions.Tools);
Assert.Null(options.ChatOptions);
}
[Fact]
@@ -107,7 +105,7 @@ public class ChatClientAgentOptionsTests
Assert.Equal(Instructions, options.Instructions);
Assert.Null(options.Description);
Assert.NotNull(options.ChatOptions);
Assert.Equal(Instructions, options.ChatOptions.Instructions);
Assert.Null(options.ChatOptions.Instructions);
Assert.Same(tools, options.ChatOptions.Tools);
}
@@ -132,7 +130,7 @@ public class ChatClientAgentOptionsTests
Assert.Equal(Instructions, options.Instructions);
Assert.Equal(Description, options.Description);
Assert.NotNull(options.ChatOptions);
Assert.Equal(Instructions, options.ChatOptions.Instructions);
Assert.Null(options.ChatOptions.Instructions);
Assert.Same(tools, options.ChatOptions.Tools);
}
@@ -165,8 +163,13 @@ public class ChatClientAgentOptionsTests
const string Name = "Test name";
const string Description = "Test description";
var tools = new List<AITool> { AIFunctionFactory.Create(() => "test") };
static ChatMessageStore ChatMessageStoreFactory(ChatClientAgentOptions.ChatMessageStoreFactoryContext ctx) => new Mock<ChatMessageStore>().Object;
static AIContextProvider AIContextProviderFactory(ChatClientAgentOptions.AIContextProviderFactoryContext ctx) => new Mock<AIContextProvider>().Object;
static ChatMessageStore ChatMessageStoreFactory(
ChatClientAgentOptions.ChatMessageStoreFactoryContext ctx) => new Mock<ChatMessageStore>().Object;
static AIContextProvider AIContextProviderFactory(
ChatClientAgentOptions.AIContextProviderFactoryContext ctx) =>
new Mock<AIContextProvider>().Object;
var original = new ChatClientAgentOptions(Instructions, Name, Description, tools)
{
@@ -1012,6 +1012,31 @@ public partial class ChatClientAgentTests
Assert.Equal("test instructions", capturedChatOptions.Instructions);
}
[Fact]
public async Task ChatOptionsMergingUsesAgentOptionsConstructorWhenRequestHasNoneAsync()
{
Mock<IChatClient> mockService = new();
ChatOptions? capturedChatOptions = null;
mockService.Setup(
s => s.GetResponseAsync(
It.IsAny<IEnumerable<ChatMessage>>(),
It.IsAny<ChatOptions>(),
It.IsAny<CancellationToken>()))
.Callback<IEnumerable<ChatMessage>, ChatOptions, CancellationToken>((msgs, opts, ct) =>
capturedChatOptions = opts)
.ReturnsAsync(new ChatResponse([new(ChatRole.Assistant, "response")]));
ChatClientAgent agent = new(mockService.Object, options: new("test instructions"));
var messages = new List<ChatMessage> { new(ChatRole.User, "test") };
// Act
await agent.RunAsync(messages);
// Assert
Assert.NotNull(capturedChatOptions);
Assert.Equal("test instructions", capturedChatOptions.Instructions);
}
/// <summary>
/// Verify that ChatOptions merging works when request has ChatOptions but agent doesn't.
/// </summary>