Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,20 @@ The A2A Java SDK provides a Java server implementation of the [Agent2Agent (A2A)
- [Add a class that creates an A2A Agent Executor](#3-add-a-class-that-creates-an-a2a-agent-executor)
- [Add an A2A Java SDK Server Maven dependency to your project](#4-add-an-a2a-java-sdk-server-maven-dependency-to-your-project)

### 1. Add the A2A Java SDK Core Maven dependency to your project
### 1. Add the A2A Java SDK Maven dependencies to your project

> **Note**: The A2A Java SDK isn't available yet in Maven Central but will be soon. For now, be
> sure to check out the latest tag (you can see the tags [here](https://github.com/a2aproject/a2a-java/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.

```xml
<dependency>
<groupId>io.a2a.sdk</groupId>
<artifactId>a2a-java-sdk-core</artifactId>
<artifactId>a2a-java-sdk-client</artifactId>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a2a-java-sdk-spec

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the README, the "Add the A2A Java SDK Core Maven dependency to your project" should be reworded to "Add the A2A Java SDK Spec Maven dependency to your project"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum not sure about this one tbh.

Now that we splitted client and server modules, there should be two different imports:

  • One for a2a-java-sdk-client if you want to use the client part of the SDK
  • One for a2a-java-sdk-server-common if you want to use the server part of the SDK

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part of the README goes through the steps for creating an A2A server agent. In this first step, the a2a-java-sdk-spec dependency needs to be added in order to be able to create the AgentCard producer and AgentExecutor producer. A later step shows how to add the a2a-java-sdk-server-quarkus or a2a-java-sdk-server-jakarta dependency to expose the A2A server endpoint. The client dependency shouldn't be needed for creating a server agent.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the dependency on a2a-java-sdk-server-quarkus or a2a-java-sdk-server-jakarta would also bring in the dependency on a2a-java-sdk-spec. So I guess the question is if we want to be explicit about it or not.

Let's see what @kabir thinks.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think transitive dependencies are fine in this case.

<version>0.2.3</version>
</dependency>
<dependency>
<groupId>io.a2a.sdk</groupId>
<artifactId>a2a-java-sdk-server-common</artifactId>
<version>0.2.3</version>
</dependency>
```
Expand Down
45 changes: 45 additions & 0 deletions client/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.a2a.sdk</groupId>
<artifactId>a2a-java-sdk-parent</artifactId>
<version>0.2.4-SNAPSHOT</version>
</parent>
<artifactId>a2a-java-sdk-client</artifactId>

<packaging>jar</packaging>

<name>Java SDK A2A Client</name>
<description>Java SDK for the Agent2Agent Protocol (A2A) - Client</description>

<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-common</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-spec</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-netty</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
package io.a2a.spec;
package io.a2a;

import java.util.Collections;
import java.util.Map;

import io.a2a.client.A2ACardResolver;
import io.a2a.http.A2AHttpClient;
import io.a2a.http.JdkA2AHttpClient;
import io.a2a.spec.A2AClientError;
import io.a2a.spec.A2AClientJSONError;
import io.a2a.spec.AgentCard;
import io.a2a.spec.Message;
import io.a2a.spec.TextPart;


/**
* Constants and utility methods related to the A2A protocol.
*/
public class A2A {

public static final String CANCEL_TASK_METHOD = "tasks/cancel";
public static final String GET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD = "tasks/pushNotificationConfig/get";
public static final String GET_TASK_METHOD = "tasks/get";
public static final String SET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD = "tasks/pushNotificationConfig/set";
public static final String SEND_TASK_RESUBSCRIPTION_METHOD = "tasks/resubscribe";
public static final String SEND_STREAMING_MESSAGE_METHOD = "message/stream";
public static final String SEND_MESSAGE_METHOD = "message/send";

public static final String JSONRPC_VERSION = "2.0";


/**
* Convert the given text to a user message.
*
Expand Down Expand Up @@ -133,16 +127,4 @@ public static AgentCard getAgentCard(A2AHttpClient httpClient, String agentUrl,
A2ACardResolver resolver = new A2ACardResolver(httpClient, agentUrl, relativeCardPath, authHeaders);
return resolver.getAgentCard();
}

protected static boolean isValidMethodName(String methodName) {
return methodName != null && (methodName.equals(CANCEL_TASK_METHOD)
|| methodName.equals(GET_TASK_METHOD)
|| methodName.equals(GET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD)
|| methodName.equals(SET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD)
|| methodName.equals(SEND_TASK_RESUBSCRIPTION_METHOD)
|| methodName.equals(SEND_MESSAGE_METHOD)
|| methodName.equals(SEND_STREAMING_MESSAGE_METHOD));

}

}
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
package io.a2a.client;

import static io.a2a.spec.A2A.CANCEL_TASK_METHOD;
import static io.a2a.spec.A2A.GET_TASK_METHOD;
import static io.a2a.spec.A2A.GET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD;
import static io.a2a.spec.A2A.JSONRPC_VERSION;
import static io.a2a.spec.A2A.SEND_MESSAGE_METHOD;
import static io.a2a.spec.A2A.SEND_STREAMING_MESSAGE_METHOD;
import static io.a2a.spec.A2A.SEND_TASK_RESUBSCRIPTION_METHOD;
import static io.a2a.spec.A2A.SET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD;
import static io.a2a.util.Assert.checkNotNullParam;
import static io.a2a.util.Utils.OBJECT_MAPPER;
import static io.a2a.util.Utils.unmarshalFrom;

import java.io.IOException;
import java.util.Map;
Expand All @@ -24,7 +14,7 @@
import io.a2a.http.A2AHttpClient;
import io.a2a.http.A2AHttpResponse;
import io.a2a.http.JdkA2AHttpClient;
import io.a2a.spec.A2A;
import io.a2a.A2A;
import io.a2a.spec.A2AClientError;
import io.a2a.spec.A2AClientJSONError;
import io.a2a.spec.A2AServerException;
Expand All @@ -36,6 +26,7 @@
import io.a2a.spec.GetTaskRequest;
import io.a2a.spec.GetTaskResponse;
import io.a2a.spec.JSONRPCError;
import io.a2a.spec.JSONRPCMessage;
import io.a2a.spec.JSONRPCResponse;
import io.a2a.spec.MessageSendParams;
import io.a2a.spec.PushNotificationConfig;
Expand All @@ -49,6 +40,7 @@
import io.a2a.spec.TaskPushNotificationConfig;
import io.a2a.spec.TaskQueryParams;
import io.a2a.spec.TaskResubscriptionRequest;
import io.a2a.util.Utils;

/**
* An A2A client.
Expand Down Expand Up @@ -158,8 +150,8 @@ public SendMessageResponse sendMessage(MessageSendParams messageSendParams) thro
*/
public SendMessageResponse sendMessage(String requestId, MessageSendParams messageSendParams) throws A2AServerException {
SendMessageRequest.Builder sendMessageRequestBuilder = new SendMessageRequest.Builder()
.jsonrpc(JSONRPC_VERSION)
.method(SEND_MESSAGE_METHOD)
.jsonrpc(JSONRPCMessage.JSONRPC_VERSION)
.method(SendMessageRequest.METHOD)
.params(messageSendParams);

if (requestId != null) {
Expand Down Expand Up @@ -210,8 +202,8 @@ public GetTaskResponse getTask(TaskQueryParams taskQueryParams) throws A2AServer
*/
public GetTaskResponse getTask(String requestId, TaskQueryParams taskQueryParams) throws A2AServerException {
GetTaskRequest.Builder getTaskRequestBuilder = new GetTaskRequest.Builder()
.jsonrpc(JSONRPC_VERSION)
.method(GET_TASK_METHOD)
.jsonrpc(JSONRPCMessage.JSONRPC_VERSION)
.method(GetTaskRequest.METHOD)
.params(taskQueryParams);

if (requestId != null) {
Expand Down Expand Up @@ -260,8 +252,8 @@ public CancelTaskResponse cancelTask(TaskIdParams taskIdParams) throws A2AServer
*/
public CancelTaskResponse cancelTask(String requestId, TaskIdParams taskIdParams) throws A2AServerException {
CancelTaskRequest.Builder cancelTaskRequestBuilder = new CancelTaskRequest.Builder()
.jsonrpc(JSONRPC_VERSION)
.method(CANCEL_TASK_METHOD)
.jsonrpc(JSONRPCMessage.JSONRPC_VERSION)
.method(CancelTaskRequest.METHOD)
.params(taskIdParams);

if (requestId != null) {
Expand Down Expand Up @@ -310,8 +302,8 @@ public GetTaskPushNotificationConfigResponse getTaskPushNotificationConfig(TaskI
*/
public GetTaskPushNotificationConfigResponse getTaskPushNotificationConfig(String requestId, TaskIdParams taskIdParams) throws A2AServerException {
GetTaskPushNotificationConfigRequest.Builder getTaskPushNotificationRequestBuilder = new GetTaskPushNotificationConfigRequest.Builder()
.jsonrpc(JSONRPC_VERSION)
.method(GET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD)
.jsonrpc(JSONRPCMessage.JSONRPC_VERSION)
.method(GetTaskPushNotificationConfigRequest.METHOD)
.params(taskIdParams);

if (requestId != null) {
Expand Down Expand Up @@ -353,8 +345,8 @@ public SetTaskPushNotificationConfigResponse setTaskPushNotificationConfig(Strin
public SetTaskPushNotificationConfigResponse setTaskPushNotificationConfig(String requestId, String taskId,
PushNotificationConfig pushNotificationConfig) throws A2AServerException {
SetTaskPushNotificationConfigRequest.Builder setTaskPushNotificationRequestBuilder = new SetTaskPushNotificationConfigRequest.Builder()
.jsonrpc(JSONRPC_VERSION)
.method(SET_TASK_PUSH_NOTIFICATION_CONFIG_METHOD)
.jsonrpc(JSONRPCMessage.JSONRPC_VERSION)
.method(SetTaskPushNotificationConfigRequest.METHOD)
.params(new TaskPushNotificationConfig(taskId, pushNotificationConfig));

if (requestId != null) {
Expand Down Expand Up @@ -403,8 +395,8 @@ public void sendStreamingMessage(String requestId, MessageSendParams messageSend
checkNotNullParam("failureHandler", failureHandler);

SendStreamingMessageRequest.Builder sendStreamingMessageRequestBuilder = new SendStreamingMessageRequest.Builder()
.jsonrpc(JSONRPC_VERSION)
.method(SEND_STREAMING_MESSAGE_METHOD)
.jsonrpc(JSONRPCMessage.JSONRPC_VERSION)
.method(SendStreamingMessageRequest.METHOD)
.params(messageSendParams);

if (requestId != null) {
Expand Down Expand Up @@ -462,8 +454,8 @@ public void resubscribeToTask(String requestId, TaskIdParams taskIdParams, Consu
checkNotNullParam("failureHandler", failureHandler);

TaskResubscriptionRequest.Builder taskResubscriptionRequestBuilder = new TaskResubscriptionRequest.Builder()
.jsonrpc(JSONRPC_VERSION)
.method(SEND_TASK_RESUBSCRIPTION_METHOD)
.jsonrpc(JSONRPCMessage.JSONRPC_VERSION)
.method(TaskResubscriptionRequest.METHOD)
.params(taskIdParams);

if (requestId != null) {
Expand Down Expand Up @@ -502,13 +494,13 @@ private A2AHttpClient.PostBuilder createPostBuilder(Object value) throws JsonPro
return httpClient.createPost()
.url(agentUrl)
.addHeader("Content-Type", "application/json")
.body(OBJECT_MAPPER.writeValueAsString(value));
.body(Utils.OBJECT_MAPPER.writeValueAsString(value));

}

private <T extends JSONRPCResponse> T unmarshalResponse(String response, TypeReference<T> typeReference)
throws A2AServerException, JsonProcessingException {
T value = unmarshalFrom(response, typeReference);
T value = Utils.unmarshalFrom(response, typeReference);
JSONRPCError error = value.getError();
if (error != null) {
throw new A2AServerException(error.getMessage() + (error.getData() != null ? ": " + error.getData() : ""));
Expand Down
Empty file.
26 changes: 26 additions & 0 deletions common/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.a2a.sdk</groupId>
<artifactId>a2a-java-sdk-parent</artifactId>
<version>0.2.4-SNAPSHOT</version>
</parent>
<artifactId>a2a-java-sdk-common</artifactId>

<packaging>jar</packaging>

<name>Java SDK A2A Common</name>
<description>Java SDK for the Agent2Agent Protocol (A2A) - Common</description>

<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>

</project>
6 changes: 0 additions & 6 deletions core/src/main/resources/META-INF/beans.xml

This file was deleted.

100 changes: 0 additions & 100 deletions core/src/test/java/io/a2a/util/AssertTest.java

This file was deleted.

Loading