diff --git a/tests/Volcanic.AgenticCore.Telegram.Tests/A2AClientHostTests.cs b/tests/Volcanic.AgenticCore.Telegram.Tests/A2AClientHostTests.cs index cbec119..08e2d17 100644 --- a/tests/Volcanic.AgenticCore.Telegram.Tests/A2AClientHostTests.cs +++ b/tests/Volcanic.AgenticCore.Telegram.Tests/A2AClientHostTests.cs @@ -4,6 +4,9 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging.Abstractions; using Volcanic.AgenticCore.A2A.Server; +using Volcanic.AgenticCore.A2A.Server.Agent; +using Volcanic.AgenticCore.A2A.Server.Callers; +using Volcanic.AgenticCore.Features.Extensions; using Volcanic.AgenticCore.Extensions.A2A; using Volcanic.AgenticCore.Telegram.A2A; using Volcanic.AgenticCore.Telegram.Tests.Support; @@ -160,4 +163,38 @@ public class A2AClientHostTests await Wait.UntilAsync(() => PendingFile.Read(ws).Count == 0, "the record to be removed"); await ((IHostedService)service).StopAsync(CancellationToken.None); } + + [Fact] + public async Task BothOn_A2aServerSessionHasNoA2aTool_ChatHasIt() + { + var client = new A2AClientSettings { Enabled = true }; + var server = new A2AHostOptions { Enabled = true, PublicUrl = "https://bot.example" }; + await using var registry = new A2AWatchRegistry(TimeProvider.System, new HttpClientHandler()); + await using var host = new ChatHost((h, s) => + { + s.AddLogging(); + s.AddSingleton(_ => h.Chats); + s.AddSingleton(_ => h.Settings); + TelegramA2AClientSetup.Register(s, client, server, registry); // as Program.cs: before the server setup + TelegramA2ASetup.Register(s, h.Options, server); + }, a2aClient: client); + Assert.Contains((await host.ChatAsync()).Session.Tools, t => t.Name == "a2a"); + var pool = host.Services.GetRequiredService(); + var caller = new A2ACaller("travel-bot", "isolated", host.WorkspaceOf(), $"telegram-{Updates.AllowedUser}", Updates.AllowedUser.ToString()); + using var lease = await pool.AcquireAsync(caller, "ctx1", "task1", CancellationToken.None); + Assert.DoesNotContain(lease.Session.Tools, t => t.Name == "a2a"); + Assert.NotEmpty(lease.Session.Tools); + } + + [Fact] + public async Task ClientExtension_CannotBeActivatedHostWide() + { + // As if discovered from an extensions folder: its target can't come from DI, so it never loads host-wide. + await using var host = new ChatHost((_, s) => s.AddSingleton(new A2AClientSettings { Enabled = true }), + core: o => o.Extensions.Add(ExtensionRegistration.FromType(typeof(A2AClientExtension), "test"))); + var chat = await host.ChatAsync(); + Assert.DoesNotContain(chat.Session.Tools, t => t.Name == "a2a"); + var registration = ExtensionRegistration.FromType(typeof(A2AClientExtension), "test"); + Assert.ThrowsAny(() => registration.Factory(host.Services)); + } }