feat(a2a): standalone A2A sample host

This commit is contained in:
EugeneTes
2026-10-07 13:45:53 +00:00
parent baddd320c7
commit 93a4504607
3 changed files with 57 additions and 0 deletions

View File

@@ -12,6 +12,7 @@
<Project Path="hosts/Volcanic.AgenticCore.Telegram/Volcanic.AgenticCore.Telegram.csproj" /> <Project Path="hosts/Volcanic.AgenticCore.Telegram/Volcanic.AgenticCore.Telegram.csproj" />
</Folder> </Folder>
<Folder Name="/samples/"> <Folder Name="/samples/">
<Project Path="samples/Volcanic.AgenticCore.Sample.A2A/Volcanic.AgenticCore.Sample.A2A.csproj" />
<Project Path="samples/Volcanic.AgenticCore.Sample.Headless/Volcanic.AgenticCore.Sample.Headless.csproj" /> <Project Path="samples/Volcanic.AgenticCore.Sample.Headless/Volcanic.AgenticCore.Sample.Headless.csproj" />
</Folder> </Folder>
<Folder Name="/src/"> <Folder Name="/src/">

View File

@@ -0,0 +1,50 @@
// Minimal standalone A2A server over one workspace.
//
// dotnet run --project samples/Volcanic.AgenticCore.Sample.A2A -- --faux --workspace /tmp/ws
// (callers in /tmp/ws/.volcanic/a2a/callers.json; card at http://localhost:5000/.well-known/agent-card.json)
using Microsoft.Extensions.Logging;
using Volcanic.AgenticCore.A2A.Server.Callers;
using Volcanic.AgenticCore.A2A.Server.Hosting;
using Volcanic.AgenticCore.Extensions.ClaudeCode;
using Volcanic.AgenticCore.Features.Extensions;
using Volcanic.AgenticCore.Hosting;
using Volcanic.AgenticCore.Testing;
var faux = args.Contains("--faux");
var workspaceIndex = Array.IndexOf(args, "--workspace");
var workspace = Path.GetFullPath(workspaceIndex >= 0 && workspaceIndex + 1 < args.Length ? args[workspaceIndex + 1] : Directory.GetCurrentDirectory());
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAgenticCore(o =>
{
if (faux)
{
var provider = new FauxProvider();
o.Extensions.Add(ExtensionRegistration.FromInstance(provider.Extension));
o.DefaultModel = FauxProvider.ModelKey;
}
else
{
o.AddExtension<ClaudeCodeProviderExtension>();
o.DefaultModel ??= "claude-code/sonnet";
}
});
builder.Services.AddSingleton<IA2ACallerDirectory>(sp => new WorkspaceCallerDirectory(
() => [new A2AWorkspace(workspace, "sample", "sample")], sp.GetRequiredService<ILogger<WorkspaceCallerDirectory>>()));
builder.Services.AddSingleton<IA2AOwnerNotifier, LogNotifier>();
builder.Services.AddA2AServer(o => builder.Configuration.GetSection(Volcanic.AgenticCore.A2A.Server.A2AHostOptions.SectionName).Bind(o));
var app = builder.Build();
app.MapA2AServer();
app.Logger.LogInformation("A2A sample serving workspace {Workspace}; callers in {File}", workspace, CallersFile.PathFor(workspace));
app.Run();
internal sealed class LogNotifier(ILogger<LogNotifier> logger) : IA2AOwnerNotifier
{
public Task NotifyAsync(A2ACaller caller, string text, CancellationToken cancellationToken)
{
logger.LogInformation("notify_owner from {Caller}: {Text}", caller.Name, text);
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<ProjectReference Include="../../src/Volcanic.AgenticCore.A2A.Server/Volcanic.AgenticCore.A2A.Server.csproj" />
<ProjectReference Include="../../extensions/Volcanic.AgenticCore.Extensions.ClaudeCode/Volcanic.AgenticCore.Extensions.ClaudeCode.csproj" />
</ItemGroup>
</Project>