// Copyright (c) Microsoft. All rights reserved. using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.AI; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.Agents.AI.Hosting.UnitTests; /// /// Unit tests for AI tool registration extensions on . /// public sealed class HostedAgentBuilderToolsExtensionsTests { [Fact] public void WithAITool_ThrowsWhenBuilderIsNull() { // Arrange var tool = new DummyAITool(); // Act & Assert Assert.Throws(() => HostedAgentBuilderExtensions.WithAITool(null!, tool)); } [Fact] public void WithAITool_ThrowsWhenToolIsNull() { // Arrange var services = new ServiceCollection(); var builder = services.AddAIAgent("test-agent", "Test instructions"); // Act & Assert Assert.Throws(() => builder.WithAITool(null!)); } [Fact] public void WithAITools_ThrowsWhenBuilderIsNull() { // Arrange var tools = new[] { new DummyAITool() }; // Act & Assert Assert.Throws(() => HostedAgentBuilderExtensions.WithAITools(null!, tools)); } [Fact] public void WithAITools_ThrowsWhenToolsArrayIsNull() { // Arrange var services = new ServiceCollection(); var builder = services.AddAIAgent("test-agent", "Test instructions"); // Act & Assert Assert.Throws(() => builder.WithAITools(null!)); } [Fact] public void RegisteredTools_ResolvesAllToolsForAgent() { // Arrange var services = new ServiceCollection(); services.AddSingleton(new MockChatClient()); var builder = services.AddAIAgent("test-agent", "Test instructions"); var tool1 = new DummyAITool(); var tool2 = new DummyAITool(); builder .WithAITool(tool1) .WithAITool(tool2); var serviceProvider = services.BuildServiceProvider(); var agent1Tools = ResolveAgentTools(serviceProvider, "test-agent"); Assert.Contains(tool1, agent1Tools); Assert.Contains(tool2, agent1Tools); } [Fact] public void RegisteredTools_IsolatedPerAgent() { var services = new ServiceCollection(); services.AddSingleton(new MockChatClient()); var builder1 = services.AddAIAgent("agent1", "Agent 1 instructions"); var builder2 = services.AddAIAgent("agent2", "Agent 2 instructions"); var tool1 = new DummyAITool(); var tool2 = new DummyAITool(); var tool3 = new DummyAITool(); builder1 .WithAITool(tool1) .WithAITool(tool2); builder2 .WithAITool(tool3); var serviceProvider = services.BuildServiceProvider(); var agent1Tools = ResolveAgentTools(serviceProvider, "agent1"); var agent2Tools = ResolveAgentTools(serviceProvider, "agent2"); Assert.Contains(tool1, agent1Tools); Assert.Contains(tool2, agent1Tools); Assert.Contains(tool3, agent2Tools); } private static IList ResolveAgentTools(IServiceProvider serviceProvider, string name) { var agent = serviceProvider.GetRequiredKeyedService(name) as ChatClientAgent; Assert.NotNull(agent?.ChatOptions?.Tools); return agent.ChatOptions.Tools; } /// /// Dummy AITool implementation for testing. /// private sealed class DummyAITool : AITool { } /// /// Mock chat client for testing. /// private sealed class MockChatClient : IChatClient { public Task GetResponseAsync(IEnumerable messages, ChatOptions? options = null, CancellationToken cancellationToken = default) { throw new NotImplementedException(); } public IAsyncEnumerable GetStreamingResponseAsync(IEnumerable messages, ChatOptions? options = null, CancellationToken cancellationToken = default) { throw new NotImplementedException(); } public object? GetService(Type serviceType, object? serviceKey = null) { return null; } public void Dispose() { throw new NotImplementedException(); } } }