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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
544 changes: 544 additions & 0 deletions .claude/architecture/compatibility_0.3.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class ExtrasBomVerifier extends DynamicBomVerifier {
"tck/", // TCK test suite
"tests/", // Integration tests
"test-utils-docker/", // Test utilities for Docker-based tests
"compat-0.3/", // Compat 0.3 modules (part of SDK BOM, not extras BOM)
"extras/queue-manager-replicated/tests-multi-instance/", // Test harness applications
"extras/queue-manager-replicated/tests-single-instance/", // Test harness applications
"extras/opentelemetry/integration-tests/" // Test harness applications
Expand Down
29 changes: 29 additions & 0 deletions boms/reference/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,35 @@
<version>${project.version}</version>
</dependency>

<!-- Multiversion reference modules -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-reference-multiversion-jsonrpc</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-reference-multiversion-rest</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Compat 0.3 Reference modules -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-compat-0.3-reference-jsonrpc</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-compat-0.3-reference-grpc</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-compat-0.3-reference-rest</artifactId>
<version>${project.version}</version>
</dependency>

<!-- TCK module for testing reference implementations -->
<dependency>
<groupId>${project.groupId}</groupId>
Expand Down
24 changes: 24 additions & 0 deletions boms/reference/src/it/reference-usage-test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,30 @@
<artifactId>a2a-java-sdk-reference-rest</artifactId>
</dependency>

<!-- Multiversion reference modules -->
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-reference-multiversion-jsonrpc</artifactId>
</dependency>
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-reference-multiversion-rest</artifactId>
</dependency>

<!-- Compat 0.3 Reference modules -->
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-reference-jsonrpc</artifactId>
</dependency>
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-reference-grpc</artifactId>
</dependency>
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-reference-rest</artifactId>
</dependency>

<!-- Core SDK modules (inherited from SDK BOM via Reference BOM) -->
<dependency>
<groupId>org.a2aproject.sdk</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@
public class ReferenceBomVerifier extends DynamicBomVerifier {

private static final Set<String> REFERENCE_EXCLUSIONS = Set.of(
"boms/", // BOM test modules themselves
"examples/", // Example applications
"tck/", // TCK test suite
"tests/", // Integration tests
"test-utils-docker/" // Test utilities for Docker-based tests
// Note: reference/ is NOT in this list - we want to verify those classes load
"boms/", // BOM test modules themselves
"examples/", // Example applications
"tck/", // TCK test suite
"tests/", // Integration tests
"test-utils-docker/", // Test utilities for Docker-based tests
"compat-0.3/client/", // Compat 0.3 client modules (part of SDK BOM)
"compat-0.3/http-client/", // Compat 0.3 HTTP client (part of SDK BOM)
"compat-0.3/tck/" // Compat 0.3 TCK (not yet enabled)
// Note: reference/ and compat-0.3/reference/ are NOT excluded - we verify those classes load
);

private static final Set<String> REFERENCE_FORBIDDEN = Set.of(
Expand Down
63 changes: 63 additions & 0 deletions boms/sdk/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,69 @@
<version>${project.version}</version>
</dependency>

<!-- Compat 0.3 Spec modules -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-compat-0.3-spec</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-compat-0.3-spec-grpc</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Compat 0.3 HTTP Client -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-compat-0.3-http-client</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Compat 0.3 Client modules -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-compat-0.3-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-compat-0.3-client-transport-spi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-compat-0.3-client-transport-jsonrpc</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-compat-0.3-client-transport-grpc</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-compat-0.3-client-transport-rest</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Compat 0.3 Transport modules -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-compat-0.3-transport-jsonrpc</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-compat-0.3-transport-grpc</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>a2a-java-sdk-compat-0.3-transport-rest</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Test utilities -->
<dependency>
<groupId>${project.groupId}</groupId>
Expand Down
52 changes: 52 additions & 0 deletions boms/sdk/src/it/sdk-usage-test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,58 @@
<artifactId>a2a-java-sdk-transport-rest</artifactId>
</dependency>

<!-- Compat 0.3 Spec modules -->
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-spec</artifactId>
</dependency>
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-spec-grpc</artifactId>
</dependency>

<!-- Compat 0.3 HTTP Client -->
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-http-client</artifactId>
</dependency>

<!-- Compat 0.3 Client modules -->
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-client</artifactId>
</dependency>
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-client-transport-spi</artifactId>
</dependency>
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-client-transport-jsonrpc</artifactId>
</dependency>
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-client-transport-grpc</artifactId>
</dependency>
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-client-transport-rest</artifactId>
</dependency>

<!-- Compat 0.3 Transport modules -->
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-transport-jsonrpc</artifactId>
</dependency>
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-transport-grpc</artifactId>
</dependency>
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-transport-rest</artifactId>
</dependency>

<!-- Third-party dependencies -->
<dependency>
<groupId>org.slf4j</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
public class SdkBomVerifier extends DynamicBomVerifier {

private static final Set<String> SDK_EXCLUSIONS = Set.of(
"boms/", // BOM test modules themselves
"examples/", // Example applications
"tck/", // TCK test suite
"tests/", // Integration tests
"test-utils-docker/" // Test utilities for Docker-based tests
"boms/", // BOM test modules themselves
"examples/", // Example applications
"tck/", // TCK test suite
"compat-0.3/tck/", // Compat 0.3 TCK (not yet enabled)
"compat-0.3/reference/", // Compat 0.3 reference implementations (in reference BOM)
"tests/", // Integration tests
"test-utils-docker/" // Test utilities for Docker-based tests
);

private static final Set<String> SDK_FORBIDDEN = Set.of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.a2aproject.sdk.jsonrpc.common.wrappers.ListTasksResult;
import org.a2aproject.sdk.spec.A2AClientException;
import org.a2aproject.sdk.spec.AgentCard;
import org.a2aproject.sdk.spec.AgentInterface;
import org.a2aproject.sdk.spec.CancelTaskParams;
import org.a2aproject.sdk.spec.DeleteTaskPushNotificationConfigParams;
import org.a2aproject.sdk.spec.EventKind;
Expand Down Expand Up @@ -388,6 +389,7 @@ private org.a2aproject.sdk.grpc.SendMessageRequest createGrpcSendMessageRequest(
*/
private Metadata createGrpcMetadata(@Nullable ClientCallContext context, @Nullable PayloadAndHeaders payloadAndHeaders) {
Metadata metadata = new Metadata();
metadata.put(VERSION_KEY, AgentInterface.CURRENT_PROTOCOL_VERSION);

if (context != null && context.getHeaders() != null) {
// Set a2a-version and a2a-extensions headers if present, ignoring case
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.google.protobuf.MessageOrBuilder;

import org.a2aproject.sdk.client.http.A2AHttpClient;
import org.a2aproject.sdk.common.A2AHeaders;
import org.a2aproject.sdk.client.http.A2AHttpClientFactory;
import org.a2aproject.sdk.client.http.A2AHttpResponse;
import org.a2aproject.sdk.client.transport.jsonrpc.sse.SSEEventListener;
Expand Down Expand Up @@ -336,6 +337,7 @@ private A2AHttpClient.PostBuilder createPostBuilder(String url, PayloadAndHeader
A2AHttpClient.PostBuilder postBuilder = httpClient.createPost()
.url(url)
.addHeader("Content-Type", "application/json")
.addHeader(A2AHeaders.A2A_VERSION, AgentInterface.CURRENT_PROTOCOL_VERSION)
.body(JSONRPCUtils.toJsonRPCRequest(null, method, (MessageOrBuilder) payloadAndHeaders.getPayload()));

if (payloadAndHeaders.getHeaders() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.a2aproject.sdk.client.http.A2AHttpClient;
import org.a2aproject.sdk.client.http.A2AHttpClientFactory;
import org.a2aproject.sdk.client.http.A2AHttpResponse;
import org.a2aproject.sdk.common.A2AHeaders;
import org.a2aproject.sdk.client.transport.rest.sse.SSEEventListener;
import org.a2aproject.sdk.client.transport.spi.ClientTransport;
import org.a2aproject.sdk.client.transport.spi.interceptors.ClientCallContext;
Expand Down Expand Up @@ -143,11 +144,7 @@ public Task getTask(TaskQueryParams taskQueryParams, @Nullable ClientCallContext
url.append(String.format("/tasks/%1s", taskQueryParams.id()));
}
A2AHttpClient.GetBuilder getBuilder = httpClient.createGet().url(url.toString());
if (payloadAndHeaders.getHeaders() != null) {
for (Map.Entry<String, String> entry : payloadAndHeaders.getHeaders().entrySet()) {
getBuilder.addHeader(entry.getKey(), entry.getValue());
}
}
addStandardHeaders(getBuilder, payloadAndHeaders);
A2AHttpResponse response = getBuilder.get();
if (!response.success()) {
throw RestErrorMapper.mapRestError(response);
Expand Down Expand Up @@ -218,11 +215,7 @@ public ListTasksResult listTasks(ListTasksParams request, @Nullable ClientCallCo
}

A2AHttpClient.GetBuilder getBuilder = httpClient.createGet().url(urlBuilder.toString());
if (payloadAndHeaders.getHeaders() != null) {
for (Map.Entry<String, String> entry : payloadAndHeaders.getHeaders().entrySet()) {
getBuilder.addHeader(entry.getKey(), entry.getValue());
}
}
addStandardHeaders(getBuilder, payloadAndHeaders);
A2AHttpResponse response = getBuilder.get();
if (!response.success()) {
throw RestErrorMapper.mapRestError(response);
Expand Down Expand Up @@ -305,11 +298,7 @@ public TaskPushNotificationConfig getTaskPushNotificationConfiguration(GetTaskPu
agentCard, context);
try {
A2AHttpClient.GetBuilder getBuilder = httpClient.createGet().url(url.toString());
if (payloadAndHeaders.getHeaders() != null) {
for (Map.Entry<String, String> entry : payloadAndHeaders.getHeaders().entrySet()) {
getBuilder.addHeader(entry.getKey(), entry.getValue());
}
}
addStandardHeaders(getBuilder, payloadAndHeaders);
A2AHttpResponse response = getBuilder.get();
if (!response.success()) {
throw RestErrorMapper.mapRestError(response);
Expand All @@ -336,11 +325,7 @@ public ListTaskPushNotificationConfigsResult listTaskPushNotificationConfigurati
try {
String url = Utils.buildBaseUrl(agentInterface, request.tenant()) + String.format("/tasks/%1s/pushNotificationConfigs", request.id());
A2AHttpClient.GetBuilder getBuilder = httpClient.createGet().url(url);
if (payloadAndHeaders.getHeaders() != null) {
for (Map.Entry<String, String> entry : payloadAndHeaders.getHeaders().entrySet()) {
getBuilder.addHeader(entry.getKey(), entry.getValue());
}
}
addStandardHeaders(getBuilder, payloadAndHeaders);
A2AHttpResponse response = getBuilder.get();
if (!response.success()) {
throw RestErrorMapper.mapRestError(response);
Expand All @@ -365,11 +350,7 @@ public void deleteTaskPushNotificationConfigurations(DeleteTaskPushNotificationC
try {
String url = Utils.buildBaseUrl(agentInterface, request.tenant()) + String.format("/tasks/%1s/pushNotificationConfigs/%2s", request.taskId(), request.id());
A2AHttpClient.DeleteBuilder deleteBuilder = httpClient.createDelete().url(url);
if (payloadAndHeaders.getHeaders() != null) {
for (Map.Entry<String, String> entry : payloadAndHeaders.getHeaders().entrySet()) {
deleteBuilder.addHeader(entry.getKey(), entry.getValue());
}
}
addStandardHeaders(deleteBuilder, payloadAndHeaders);
A2AHttpResponse response = deleteBuilder.delete();
if (!response.success()) {
throw RestErrorMapper.mapRestError(response);
Expand Down Expand Up @@ -415,9 +396,7 @@ public AgentCard getExtendedAgentCard(GetExtendedAgentCardParams params, @Nullab
PayloadAndHeaders payloadAndHeaders = applyInterceptors(GET_EXTENDED_AGENT_CARD_METHOD, null, agentCard, context);
String url = Utils.buildBaseUrl(agentInterface, params.tenant()) + "/extendedAgentCard";
A2AHttpClient.GetBuilder getBuilder = httpClient.createGet().url(url);
for (Map.Entry<String, String> entry : payloadAndHeaders.getHeaders().entrySet()) {
getBuilder.addHeader(entry.getKey(), entry.getValue());
}
addStandardHeaders(getBuilder, payloadAndHeaders);
A2AHttpResponse response = getBuilder.get();
if (!response.success()) {
throw RestErrorMapper.mapRestError(response);
Expand Down Expand Up @@ -463,6 +442,7 @@ private A2AHttpClient.PostBuilder createPostBuilder(String url, PayloadAndHeader
A2AHttpClient.PostBuilder postBuilder = httpClient.createPost()
.url(url)
.addHeader("Content-Type", "application/json")
.addHeader(A2AHeaders.A2A_VERSION, AgentInterface.CURRENT_PROTOCOL_VERSION)
.body(JsonFormat.printer().print((MessageOrBuilder) payloadAndHeaders.getPayload()));

if (payloadAndHeaders.getHeaders() != null) {
Expand All @@ -473,6 +453,15 @@ private A2AHttpClient.PostBuilder createPostBuilder(String url, PayloadAndHeader
return postBuilder;
}

private static <T extends A2AHttpClient.Builder<T>> void addStandardHeaders(T builder, PayloadAndHeaders payloadAndHeaders) {
builder.addHeader(A2AHeaders.A2A_VERSION, AgentInterface.CURRENT_PROTOCOL_VERSION);
if (payloadAndHeaders.getHeaders() != null) {
for (Map.Entry<String, String> entry : payloadAndHeaders.getHeaders().entrySet()) {
builder.addHeader(entry.getKey(), entry.getValue());
}
}
}

private Map<String, String> getHttpHeaders(@Nullable ClientCallContext context) {
return context != null ? context.getHeaders() : Collections.emptyMap();
}
Expand Down
Loading