Skip to content

Commit dce4a09

Browse files
SergeyMenshykhdarrelmillermarkwallace-microsoftCopilotbaywet
authored
feat: .net api for the a2a protocol (#1)
* classlib and unit test projects * Created an example of a worker agent that mimics deep research * Added TODOs for remaining work * Refactored projects and added more tests * Simplified JSONRPC serialization * Implement A2AProcessor and refactor task management methods for improved JSON RPC handling * Migrated (de)serialization to DomFactory * Added more agents * reordered agents * added readme * Refactor task management and enhance JSON RPC handling - Updated task status management in EchoAgent and HostedClientAgent to use async methods. - Improved task creation and update handling in TaskManager. - Added support for task subscription and event streaming. * Update README.md to reflect current library status and enhance agent integration example * Missing image * Added OpenTelemetry instrumentation * Cleanup of project names * Cleaned up namespace names * Added a client application. * Setup packages for publishing * Made Domfactory a separate package because it didn't work embedding it * Fixes #4 and #6 * Add AgentCard implementation * Update src/SharpA2A.Core/Server/TaskManager.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update test/a2atests/TaskManagerTests.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Create dotnet-build.yml GitHub actions workflow to build and test the project * Address code review feedback * Implemented client streaming * Add a sample using Semantic Kernel agents * Added sln for running AgentServer * Target .net8.0 and .netstandard2.0 to packages can be consumed by Semantic Kernel * Updated version to publish packages * Updated version numbers for publishing * Add net8.0 target for SharpA2A.AspNetCore * Update dotnet-build.yml Build using dotnet version 8 & 9 * Updated sharpa2a.aspnetcore to support .net8 * Updated OpenAPI * Fixed SendSubscribe for HTTP and also the flaky enumerator * Big refactoring and cleanup * ci: fixes missing moniker for dotnet commands Signed-off-by: Vincent Biret <vibiret@microsoft.com> * ci: adds worfklow dispatch just in case Signed-off-by: Vincent Biret <vibiret@microsoft.com> * ci: removes extraneous framework monikers Signed-off-by: Vincent Biret <vibiret@microsoft.com> * ci: adds required 9.x framework for restore Signed-off-by: Vincent Biret <vibiret@microsoft.com> * ci: removes no restore argument Signed-off-by: Vincent Biret <vibiret@microsoft.com> * ci: Signed-off-by: Vincent Biret <vibiret@microsoft.com> * fix: removes extraneous swagger description Signed-off-by: Vincent Biret <vibiret@microsoft.com> * ci: adds dependabot configuration Signed-off-by: Vincent Biret <vibiret@microsoft.com> * ci: removes dependabot tag instructions Signed-off-by: Vincent Biret <vibiret@microsoft.com> * Update: - coverlet.collector to 6.0.4 - Microsoft.Extensions.Hosting to 9.0.5 - Microsoft.Extensions.Logging to 9.0.5 - Microsoft.NET.Test.Sdk to 17.13.0 - Microsoft.SemanticKernel.Agents.Core to 1.51.0 - OpenTelemetry.Instrumentation.Runtime to 1.12.0 - System.Net.ServerSentEvents to 9.0.5 - xunit to 2.9.3 - xunit.runner.visualstudio to 3.1.0 --- updated-dependencies: - dependency-name: coverlet.collector dependency-version: 6.0.4 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Microsoft.Extensions.Hosting dependency-version: 9.0.5 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Microsoft.Extensions.Logging dependency-version: 9.0.5 dependency-type: direct:production update-type: version-update:semver-major - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 17.13.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: Microsoft.SemanticKernel.Agents.Core dependency-version: 1.51.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: OpenTelemetry.Instrumentation.Runtime dependency-version: 1.12.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: System.Net.ServerSentEvents dependency-version: 9.0.5 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: xunit dependency-version: 2.9.3 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: xunit.runner.visualstudio dependency-version: 3.1.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Update Microsoft.NET.Test.Sdk to 17.14.0 --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 17.14.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: Microsoft.SemanticKernel.Agents.Core dependency-version: 1.53.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Fixed SK Travel Agent demo * Split build between libs and samples to enable multiframework lib building * Fixed framework versions * Limit sample building to net9.0 * fixed paths for ubuntu * Always setup 9.0 * Updated version to preview.5 * feat: Updated a2a protocol and changed serialization * Updated TaskManager to support new SendMessage. WIP * It builds and the tests pass! * Return Task as first event in stream * feat: Introduce MessageRole enum and update message handling in EchoAgent and HostedClientAgent * chore: Changed some package dependencies to be more flexible * Tested samples * Fixed sln file * Fix logging of taskId Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Did some client renaming and added resubscribe method * Updated JSON Schema used by tests * Update README.md * Updated version to 0.2.1 to match protocol version * rename namespace * rename projects * rename solution file and migrate it to slnx format * add a2a project * enable central package management * review dependencies * update repo and project urls * update project descriptions, tags, etc * reference readme file * move unit test project to tests folder * rename a2atests project and test folder * add test project per project * move unit tests to test projects they belong * add root namespace to test projects and updated the namespaces accordingly. * update license identifier * update tags, author, and package version * add gitignore to solution items * fix build and run action * fix warnings * fix property name * Update README.md Co-authored-by: Stephen Toub <stoub@microsoft.com> --------- Signed-off-by: Vincent Biret <vibiret@microsoft.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Darrel Miller <darrel.miller@microsoft.com> Co-authored-by: markwallace-microsoft <127216156+markwallace-microsoft@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Vincent Biret <vibiret@microsoft.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Stephen Toub <stoub@microsoft.com>
1 parent 708f6f3 commit dce4a09

File tree

98 files changed

+10908
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+10908
-2
lines changed

.github/dependabot.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: nuget
4+
directory: "/"
5+
schedule:
6+
interval: daily
7+
open-pull-requests-limit: 10
8+
groups:
9+
OpenTelemetry:
10+
patterns:
11+
- "OpenTelemetry.*"
12+
- "Azure.Monitor.OpenTelemetry.Exporter"
13+
- package-ecosystem: github-actions
14+
directory: "/"
15+
schedule:
16+
interval: daily
17+
open-pull-requests-limit: 10

.github/workflows/dotnet-build.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# This workflow will build a .NET project
2+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net
3+
4+
name: .NET
5+
on:
6+
push:
7+
branches: [ "main" ]
8+
pull_request:
9+
branches: [ "main" ]
10+
workflow_dispatch:
11+
12+
jobs:
13+
buildLibs:
14+
runs-on: ubuntu-latest
15+
strategy:
16+
matrix:
17+
include:
18+
- dotnet-version: 8.x
19+
framework: net8.0
20+
- dotnet-version: 9.x
21+
framework: net9.0
22+
steps:
23+
- uses: actions/checkout@v4
24+
- name: Setup .NET 9.x
25+
uses: actions/setup-dotnet@v4
26+
with:
27+
dotnet-version: 9.x
28+
- name: Setup .NET ${{ matrix.dotnet-version }}
29+
uses: actions/setup-dotnet@v4
30+
with:
31+
dotnet-version: ${{ matrix.dotnet-version }}
32+
- name: Restore dependencies
33+
run: dotnet restore
34+
- name: BuildLibs
35+
run: dotnet build ./src/A2ALibs.slnx --framework ${{ matrix.framework }}
36+
- name: TestLibs
37+
run: dotnet test ./src/A2ALibs.slnx --no-build --verbosity normal --framework ${{ matrix.framework }}
38+
buildSamples:
39+
runs-on: ubuntu-latest
40+
steps:
41+
- uses: actions/checkout@v4
42+
- name: Setup .NET 9.x
43+
uses: actions/setup-dotnet@v4
44+
with:
45+
dotnet-version: 9.x
46+
- name: Restore dependencies
47+
run: dotnet restore
48+
- name: BuildLibs
49+
run: dotnet build --framework net9.0
50+
- name: TestLibs
51+
run: dotnet test --no-build --verbosity normal --framework net9.0

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
##
88
## Get latest from https://github.com/github/gitignore/blob/main/Dotnet.gitignore
99

10+
# Visual Studio files
11+
.vs/
12+
*.user
13+
*.userosscache
14+
*.sln.docstates
15+
*.userprefs
1016
# Build results
1117
[Dd]ebug/
1218
[Dd]ebugPublic/

A2A.slnx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Solution>
2+
<Folder Name="/samples/">
3+
<Project Path="samples/A2ACli/A2ACli.csproj" />
4+
<Project Path="samples/AgentServer/AgentServer.csproj" />
5+
<Project Path="samples/Client/Client.csproj" />
6+
<Project Path="samples/SemanticKernelAgent/SemanticKernelAgent.csproj" />
7+
</Folder>
8+
<Folder Name="/src/">
9+
<Project Path="src/A2A/A2A.csproj" />
10+
<Project Path="src/A2A.Core/A2A.Core.csproj" />
11+
<Project Path="src/A2A.AspNetCore/A2A.AspNetCore.csproj" />
12+
</Folder>
13+
<Folder Name="/Solution Items/">
14+
<File Path=".gitignore" />
15+
<File Path="Directory.Build.props" />
16+
<File Path="Directory.Packages.props" />
17+
<File Path="README.md" />
18+
</Folder>
19+
<Folder Name="/tests/">
20+
<Project Path="tests/A2A.AspNetCore.UnitTests/A2A.AspNetCore.UnitTests.csproj" />
21+
<Project Path="tests/A2A.Core.UnitTests/A2A.Core.UnitTests.csproj" />
22+
<Project Path="tests/A2A.UnitTests/A2A.UnitTests.csproj" />
23+
</Folder>
24+
</Solution>

Directory.Build.props

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<Project>
2+
<PropertyGroup>
3+
<Version>0.1.0-preview.1</Version>
4+
<Authors>Community Contributors</Authors>
5+
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
6+
<PackageProjectUrl>https://github.com/a2aproject/a2a-dotnet</PackageProjectUrl>
7+
<RepositoryUrl>https://github.com/a2aproject/a2a-dotnet</RepositoryUrl>
8+
<RepositoryType>git</RepositoryType>
9+
<PackageTags>Agent2Agent;a2a;agent;ai;llm</PackageTags>
10+
<IncludeSymbols>true</IncludeSymbols>
11+
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
12+
</PropertyGroup>
13+
14+
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
15+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
16+
</PropertyGroup>
17+
18+
<PropertyGroup>
19+
<LangVersion>12.0</LangVersion>
20+
<Nullable>enable</Nullable>
21+
</PropertyGroup>
22+
23+
</Project>

Directory.Packages.props

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<Project>
2+
<PropertyGroup>
3+
<!-- Enable central package management, https://learn.microsoft.com/en-us/nuget/consume-packages/Central-Package-Management -->
4+
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<!-- Microsoft Extensions -->
8+
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.5" />
9+
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.5" />
10+
<!-- Microsoft Semantic Kernel -->
11+
<PackageVersion Include="Microsoft.SemanticKernel.Agents.Core" Version="1.53.1" />
12+
<PackageVersion Include="Microsoft.SemanticKernel.Agents.OpenAI" Version="1.53.1-preview" />
13+
<!-- OpenTelemetry -->
14+
<PackageVersion Include="OpenTelemetry" Version="1.12.0" />
15+
16+
<PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.12.0" />
17+
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.12.0" />
18+
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.12.0" />
19+
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.12.0" />
20+
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.12.0" />
21+
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.12.0" />
22+
<!-- System Packages -->
23+
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
24+
<PackageVersion Include="System.Net.ServerSentEvents" Version="9.0.5" />
25+
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
26+
<!-- JSON Schema -->
27+
<PackageVersion Include="JsonSchema.Net" Version="7.3.4" />
28+
<!-- Resilience & Utilities -->
29+
<PackageVersion Include="Polly" Version="8.4.2" />
30+
<!-- Test Packages -->
31+
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
32+
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
33+
<PackageVersion Include="xunit" Version="2.9.3" />
34+
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.0" />
35+
</ItemGroup>
36+
</Project>

README.md

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,66 @@
1-
# a2a-dotnet
2-
C#/.NET SDK for A2A Protocol
1+
# A2A: A .NET implementation of the Google A2A protocol
2+
Interact with agents using the A2A protocol in .NET applications. This library is designed to be used with ASP.NET Core applications and provides a simple way to add A2A support to your agents.
3+
4+
## Status
5+
6+
This library has implemented the majority of the protocol v0.2.1, however there are likely some scenarios that are still not complete. The biggest piece of functionality that is missing is client callbacks using push notifications.
7+
8+
## Overview
9+
![alt text](overview.png)
10+
11+
12+
## Library: a2a.AspNetCore
13+
This library adds the MapA2A extension method that allows you to add A2A support to an Agent hosted at the specified path.
14+
15+
```c#
16+
var echoAgent = new EchoAgent();
17+
var echoTaskManager = new TaskManager();
18+
echoAgent.Attach(echoTaskManager);
19+
app.MapA2A(echoTaskManager,"/echo");
20+
```
21+
22+
## Library: A2A.Core
23+
This library contains the core A2A protocol implementation. It includes the following classes:
24+
- `A2AClient`: Used for making A2A requests to an agent.
25+
- `TaskManager`: Provides standardized support for managing tasks and task execution.
26+
- `ITaskStore`: An interface for abstracting the storage of tasks. `InMemoryTaskStore` is a simple in-memory implementation.
27+
28+
## Library: DomFactory
29+
This library contains helper classes for support deserialization and serialization of A2A messages and JsonRPC envelopes. In theory this can be done with JsonSerializer, but this library makes the process easier to debug and doesn't require an reflection or code generation.
30+
31+
## Agent Integration Example
32+
33+
Each agent instance should be given its own `TaskManager` instance. The `TaskManager` is responsible for managing the tasks and their execution. It is an implementation decision as to whether a single agent instance processes many tasks or whether an agent instance is created for each task.
34+
35+
```c#
36+
using A2A.Core;
37+
38+
public class EchoAgent
39+
{
40+
private TaskManager? _TaskManager;
41+
42+
public void Attach(TaskManager taskManager)
43+
{
44+
_TaskManager = taskManager;
45+
taskManager.OnTaskCreated = ExecuteAgentTask;
46+
taskManager.OnTaskUpdated = ExecuteAgentTask;
47+
}
48+
49+
public async Task ExecuteAgentTask(AgentTask task) {
50+
if (_TaskManager == null) {
51+
throw new Exception("TaskManager is not attached.");
52+
}
53+
// Set Status to working
54+
await _TaskManager.UpdateStatusAsync(task.Id, TaskState.Working);
55+
56+
var message = task.History!.Last().Parts.First().AsTextPart().Text;
57+
var artifact = new Artifact() {
58+
Parts = [new TextPart() {
59+
Text = $"Echo: {message}"
60+
}]
61+
};
62+
await _TaskManager.ReturnArtifactAsync(new TaskIdParams() {Id = task.Id}, artifact);
63+
await _TaskManager.UpdateStatusAsync(task.Id, TaskState.Completed, final: true);
64+
}
65+
}
66+
```

overview.png

169 KB
Loading

samples/A2ACli/A2ACli.csproj

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net9.0</TargetFramework>
6+
<RootNamespace>A2A</RootNamespace>
7+
<AssemblyName>A2A.Cli</AssemblyName>
8+
<LangVersion>12</LangVersion>
9+
<ImplicitUsings>enable</ImplicitUsings>
10+
<Nullable>enable</Nullable>
11+
</PropertyGroup>
12+
13+
<ItemGroup>
14+
<PackageReference Include="System.CommandLine" />
15+
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
16+
</ItemGroup>
17+
18+
<ItemGroup>
19+
<ProjectReference Include="..\..\src\A2A.Core\A2A.Core.csproj" />
20+
</ItemGroup>
21+
22+
</Project>

0 commit comments

Comments
 (0)