Skip to content

Commit 80cb1ea

Browse files
authored
Merge pull request #118 from fjuma/spec
Add details about the A2A server implementation to the README and update the project version to 0.2.3-SNAPSHOT
2 parents a486a1f + 9122dd0 commit 80cb1ea

File tree

9 files changed

+208
-12
lines changed

9 files changed

+208
-12
lines changed

README.md

Lines changed: 200 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,206 @@
1-
# Java A2A SDK (WIP)
1+
# A2A Java SDK
22

3-
This project (currently WIP) will provide a Java SDK implementation of Google's [Agent2Agent protocol (A2A)](https://google.github.io/A2A/).
3+
<html>
4+
<h3 align="center">A Java library that helps run agentic applications as A2AServers following Google's <a href="https://google-a2a.github.io/A2A">Agent2Agent (A2A) Protocol</a>.</h3>
5+
</html>
46

5-
## Specification
7+
## Installation
68

7-
The majority of the classes required by the specification can currently be found in the [src/main/java/io/a2a/spec](https://github.com/fjuma/a2a-java-sdk/tree/main/src/main/java/io/a2a/spec) directory.
9+
You can build the A2A Java SDK using `mvn`:
10+
11+
```bash
12+
mvn clean install
13+
```
14+
15+
## Examples
16+
17+
You can find an example of how to use the A2A Java SDK [here](https://github.com/fjuma/a2a-samples/tree/java-sdk-example/samples/multi_language/python_and_java_multiagent/weather_agent).
18+
19+
More examples will be added soon.
20+
21+
## A2A Server
22+
23+
The A2A Java SDK provides a Java server implementation of the [Agent2Agent (A2A) Protocol](https://google-a2a.github.io/A2A). To run your agentic Java application as an A2A server, simply follow the steps below.
24+
25+
- [Add the A2A Java SDK Core Maven dependency to your project](#1-add-the-a2a-java-sdk-core-maven-dependency-to-your-project)
26+
- [Add a class that creates an A2A Agent Card](#2-add-a-class-that-creates-an-a2a-agent-card)
27+
- [Add a class that creates an A2A Agent Executor](#3-add-a-class-that-creates-an-a2a-agent-executor)
28+
- [Add an A2A Java SDK Server Maven dependency to your project](#4-add-an-a2a-java-sdk-server-maven-dependency-to-your-project)
29+
30+
### 1. Add the A2A Java SDK Core Maven dependency to your project
31+
32+
> **Note**: The A2A Java SDK isn't available yet in Maven Central but will be soon. For now, be
33+
> sure to check out the latest tag (you can see the tags [here](https://github.com/fjuma/a2a-java-sdk/tags)), build from the tag, and reference that version below. For example, if the latest tag is `0.2.3`, you can use the following dependency.
34+
35+
```xml
36+
<dependency>
37+
<groupId>io.a2a.sdk</groupId>
38+
<artifactId>a2a-java-sdk-core</artifactId>
39+
<version>0.2.3</version>
40+
</dependency>
41+
```
42+
43+
### 2. Add a class that creates an A2A Agent Card
44+
45+
```java
46+
import io.a2a.spec.AgentCapabilities;
47+
import io.a2a.spec.AgentCard;
48+
import io.a2a.spec.AgentSkill;
49+
import io.a2a.spec.PublicAgentCard;
50+
...
51+
52+
@ApplicationScoped
53+
public class WeatherAgentCardProducer {
54+
55+
@Produces
56+
@PublicAgentCard
57+
public AgentCard agentCard() {
58+
return new AgentCard.Builder()
59+
.name("Weather Agent")
60+
.description("Helps with weather")
61+
.url("http://localhost:10001")
62+
.version("1.0.0")
63+
.capabilities(new AgentCapabilities.Builder()
64+
.streaming(true)
65+
.pushNotifications(false)
66+
.stateTransitionHistory(false)
67+
.build())
68+
.defaultInputModes(Collections.singletonList("text"))
69+
.defaultOutputModes(Collections.singletonList("text"))
70+
.skills(Collections.singletonList(new AgentSkill.Builder()
71+
.id("weather_search")
72+
.name("Search weather")
73+
.description("Helps with weather in city, or states")
74+
.tags(Collections.singletonList("weather"))
75+
.examples(List.of("weather in LA, CA"))
76+
.build()))
77+
.build();
78+
}
79+
}
80+
```
81+
82+
### 3. Add a class that creates an A2A Agent Executor
83+
84+
```java
85+
import io.a2a.server.agentexecution.AgentExecutor;
86+
import io.a2a.server.agentexecution.RequestContext;
87+
import io.a2a.server.events.EventQueue;
88+
import io.a2a.server.tasks.TaskUpdater;
89+
import io.a2a.spec.JSONRPCError;
90+
import io.a2a.spec.Message;
91+
import io.a2a.spec.Part;
92+
import io.a2a.spec.Task;
93+
import io.a2a.spec.TaskNotCancelableError;
94+
import io.a2a.spec.TaskState;
95+
import io.a2a.spec.TextPart;
96+
...
97+
98+
@ApplicationScoped
99+
public class WeatherAgentExecutorProducer {
100+
101+
@Inject
102+
WeatherAgent weatherAgent;
103+
104+
@Produces
105+
public AgentExecutor agentExecutor() {
106+
return new WeatherAgentExecutor(weatherAgent);
107+
}
108+
109+
private static class WeatherAgentExecutor implements AgentExecutor {
110+
111+
private final WeatherAgent weatherAgent;
112+
113+
public WeatherAgentExecutor(WeatherAgent weatherAgent) {
114+
this.weatherAgent = weatherAgent;
115+
}
116+
117+
@Override
118+
public void execute(RequestContext context, EventQueue eventQueue) throws JSONRPCError {
119+
TaskUpdater updater = new TaskUpdater(context, eventQueue);
120+
121+
// mark the task as submitted and start working on it
122+
if (context.getTask() == null) {
123+
updater.submit();
124+
}
125+
updater.startWork();
126+
127+
// extract the text from the message
128+
String userMessage = extractTextFromMessage(context.getMessage());
129+
130+
// call the weather agent with the user's message
131+
String response = weatherAgent.chat(userMessage);
132+
133+
// create the response part
134+
TextPart responsePart = new TextPart(response, null);
135+
List<Part<?>> parts = List.of(responsePart);
136+
137+
// add the response as an artifact and complete the task
138+
updater.addArtifact(parts, null, null, null);
139+
updater.complete();
140+
}
141+
142+
private String extractTextFromMessage(Message message) {
143+
StringBuilder textBuilder = new StringBuilder();
144+
if (message.getParts() != null) {
145+
for (Part part : message.getParts()) {
146+
if (part instanceof TextPart textPart) {
147+
textBuilder.append(textPart.getText());
148+
}
149+
}
150+
}
151+
return textBuilder.toString();
152+
}
153+
154+
@Override
155+
public void cancel(RequestContext context, EventQueue eventQueue) throws JSONRPCError {
156+
Task task = context.getTask();
157+
158+
if (task.getStatus().state() == TaskState.CANCELED) {
159+
// task already cancelled
160+
throw new TaskNotCancelableError();
161+
}
162+
163+
if (task.getStatus().state() == TaskState.COMPLETED) {
164+
// task already completed
165+
throw new TaskNotCancelableError();
166+
}
167+
168+
// cancel the task
169+
TaskUpdater updater = new TaskUpdater(context, eventQueue);
170+
updater.cancel();
171+
}
172+
}
173+
}
174+
```
175+
176+
### 4. Add an A2A Java SDK Server Maven dependency to your project
177+
178+
> **Note**: The A2A Java SDK isn't available yet in Maven Central but will be soon. For now, be
179+
> sure to check out the latest tag (you can see the tags [here](https://github.com/fjuma/a2a-java-sdk/tags)), build from the tag, and reference that version below. For example, if the latest tag is `0.2.3`, you can use the following dependency.
180+
181+
Adding a dependency on an A2A Java SDK Server will allow you to run your agentic Java application as an A2A server.
182+
183+
The A2A Java SDK provides two A2A server endpoint implementations, one based on Jakarta REST (`a2a-java-sdk-server-jakarta`) and one based on Quarkus Reactive Routes (`a2a-java-sdk-server-quarkus`). You can choose the one that best fits your application.
184+
185+
Add **one** of the following dependencies to your project:
186+
187+
```xml
188+
<dependency>
189+
<groupId>io.a2a.sdk</groupId>
190+
<artifactId>a2a-java-sdk-server-jakarta</artifactId>
191+
<version>${io.a2a.sdk.version}</version>
192+
</dependency>
193+
```
194+
195+
OR
196+
197+
```xml
198+
<dependency>
199+
<groupId>io.a2a.sdk</groupId>
200+
<artifactId>a2a-java-sdk-server-quarkus</artifactId>
201+
<version>${io.a2a.sdk.version}</version>
202+
</dependency>
203+
```
8204

9205
## Client
10206

core/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>io.a2a.sdk</groupId>
99
<artifactId>a2a-java-sdk-parent</artifactId>
10-
<version>1.0.0-SNAPSHOT</version>
10+
<version>0.2.3-SNAPSHOT</version>
1111
</parent>
1212
<artifactId>a2a-java-sdk-core</artifactId>
1313

examples/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>io.a2a.sdk</groupId>
99
<artifactId>a2a-java-sdk-parent</artifactId>
10-
<version>1.0.0-SNAPSHOT</version>
10+
<version>0.2.3-SNAPSHOT</version>
1111
</parent>
1212

1313
<artifactId>a2a-java-sdk-examples</artifactId>

examples/src/main/java/io/a2a/examples/helloworld/client/HelloWorldRunner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
///usr/bin/env jbang "$0" "$@" ; exit $?
22
//REPOS file://~/.m2/repository/
3-
//DEPS io.a2a.sdk:a2a-java-sdk:1.0.0-SNAPSHOT
3+
//DEPS io.a2a.sdk:a2a-java-sdk:0.2.3-SNAPSHOT
44
//SOURCES HelloWorldClient.java
55

66
/**

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>io.a2a.sdk</groupId>
88
<artifactId>a2a-java-sdk-parent</artifactId>
9-
<version>1.0.0-SNAPSHOT</version>
9+
<version>0.2.3-SNAPSHOT</version>
1010

1111
<packaging>pom</packaging>
1212

sdk-jakarta/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>io.a2a.sdk</groupId>
99
<artifactId>a2a-java-sdk-parent</artifactId>
10-
<version>1.0.0-SNAPSHOT</version>
10+
<version>0.2.3-SNAPSHOT</version>
1111
</parent>
1212
<artifactId>a2a-java-sdk-server-jakarta</artifactId>
1313

sdk-quarkus/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>io.a2a.sdk</groupId>
99
<artifactId>a2a-java-sdk-parent</artifactId>
10-
<version>1.0.0-SNAPSHOT</version>
10+
<version>0.2.3-SNAPSHOT</version>
1111
</parent>
1212
<artifactId>a2a-java-sdk-server-quarkus</artifactId>
1313

tck/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>io.a2a.sdk</groupId>
99
<artifactId>a2a-java-sdk-parent</artifactId>
10-
<version>1.0.0-SNAPSHOT</version>
10+
<version>0.2.3-SNAPSHOT</version>
1111
</parent>
1212

1313
<artifactId>a2a-tck-server</artifactId>

tests/server-common/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>io.a2a.sdk</groupId>
99
<artifactId>a2a-java-sdk-parent</artifactId>
10-
<version>1.0.0-SNAPSHOT</version>
10+
<version>0.2.3-SNAPSHOT</version>
1111
<relativePath>../../pom.xml</relativePath>
1212
</parent>
1313
<artifactId>a2a-java-sdk-tests-server-common</artifactId>

0 commit comments

Comments
 (0)