Skip to content

Commit cb084ec

Browse files
ehsavoiekabir
andauthored
feat!: Updating to newest proto to align with 1.0 Draft specifications (#484)
[Feat]: Use protobuf as the serialization mechanism Fixes #<issue_number_goes_here> 🦕 --------- Signed-off-by: Emmanuel Hugonnet <[email protected]> Co-authored-by: Kabir Khan <[email protected]>
1 parent 686e40a commit cb084ec

File tree

234 files changed

+10655
-6594
lines changed

Some content is hidden

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

234 files changed

+10655
-6594
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ We copy https://github.com/a2aproject/A2A/blob/main/specification/grpc/a2a.proto
2424
```
2525
option java_package = "io.a2a.grpc";
2626
```
27-
Then build the `spec-grpc` module with `mvn clean install -Pproto-compile` to regenerate the gRPC classes in the `io.a2a.grpc` package.
27+
Then build the `spec-grpc` module with `mvn clean install -Dskip.protobuf.generate=false` to regenerate the gRPC classes in the `io.a2a.grpc` package.
2828

2929
## Examples
3030

boms/sdk/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@
155155
<dependency>
156156
<groupId>com.google.protobuf</groupId>
157157
<artifactId>protobuf-java</artifactId>
158-
<version>${protobuf.version}</version>
158+
<version>${protobuf-java.version}</version>
159159
</dependency>
160160
<dependency>
161161
<groupId>io.smallrye.reactive</groupId>

client/base/src/main/java/io/a2a/client/ClientBuilder.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,29 +92,29 @@ private ClientTransport buildClientTransport() throws A2AClientException {
9292
AgentInterface agentInterface = findBestClientTransport();
9393

9494
// Get the transport provider associated with the protocol
95-
ClientTransportProvider clientTransportProvider = transportProviderRegistry.get(agentInterface.transport());
95+
ClientTransportProvider clientTransportProvider = transportProviderRegistry.get(agentInterface.protocolBinding());
9696
if (clientTransportProvider == null) {
97-
throw new A2AClientException("No client available for " + agentInterface.transport());
97+
throw new A2AClientException("No client available for " + agentInterface.protocolBinding());
9898
}
9999
Class<? extends ClientTransport> transportProtocolClass = clientTransportProvider.getTransportProtocolClass();
100100

101101
// Retrieve the configuration associated with the preferred transport
102102
ClientTransportConfig<? extends ClientTransport> clientTransportConfig = clientTransports.get(transportProtocolClass);
103103

104104
if (clientTransportConfig == null) {
105-
throw new A2AClientException("Missing required TransportConfig for " + agentInterface.transport());
105+
throw new A2AClientException("Missing required TransportConfig for " + agentInterface.protocolBinding());
106106
}
107107

108108
return clientTransportProvider.create(clientTransportConfig, agentCard, agentInterface.url());
109109
}
110110

111-
private Map<String, String> getServerPreferredTransports() {
111+
private Map<String, String> getServerPreferredTransports() throws A2AClientException {
112112
Map<String, String> serverPreferredTransports = new LinkedHashMap<>();
113-
serverPreferredTransports.put(agentCard.preferredTransport(), agentCard.url());
114-
if (agentCard.additionalInterfaces() != null) {
115-
for (AgentInterface agentInterface : agentCard.additionalInterfaces()) {
116-
serverPreferredTransports.putIfAbsent(agentInterface.transport(), agentInterface.url());
117-
}
113+
if(agentCard.supportedInterfaces() == null || agentCard.supportedInterfaces().isEmpty()) {
114+
throw new A2AClientException("No server interface available in the AgentCard");
115+
}
116+
for (AgentInterface agentInterface : agentCard.supportedInterfaces()) {
117+
serverPreferredTransports.putIfAbsent(agentInterface.protocolBinding(), agentInterface.url());
118118
}
119119
return serverPreferredTransports;
120120
}

client/base/src/test/java/io/a2a/client/AuthenticationAuthorizationTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ public void setUp() {
7777
agentCard = new AgentCard.Builder()
7878
.name("Test Agent")
7979
.description("Test agent for auth tests")
80-
.url(AGENT_URL)
8180
.version("1.0.0")
8281
.capabilities(new AgentCapabilities.Builder()
8382
.streaming(true) // Support streaming for all tests
@@ -91,7 +90,7 @@ public void setUp() {
9190
.tags(Collections.singletonList("test"))
9291
.build()))
9392
.protocolVersion("0.3.0")
94-
.additionalInterfaces(java.util.Arrays.asList(
93+
.supportedInterfaces(java.util.Arrays.asList(
9594
new AgentInterface(TransportProtocol.JSONRPC.asString(), AGENT_URL),
9695
new AgentInterface(TransportProtocol.HTTP_JSON.asString(), AGENT_URL),
9796
new AgentInterface(TransportProtocol.GRPC.asString(), grpcServerName)))

client/base/src/test/java/io/a2a/client/ClientBuilderTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public class ClientBuilderTest {
2424
private AgentCard card = new AgentCard.Builder()
2525
.name("Hello World Agent")
2626
.description("Just a hello world agent")
27-
.url("http://localhost:9999")
27+
.supportedInterfaces(Collections.singletonList(new AgentInterface("jsonrpc", "http://localhost:9999")))
2828
.version("1.0.0")
2929
.documentationUrl("http://example.com/docs")
3030
.capabilities(new AgentCapabilities.Builder()

client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransport.java

Lines changed: 46 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -16,36 +16,32 @@
1616
import io.a2a.grpc.A2AServiceGrpc;
1717
import io.a2a.grpc.A2AServiceGrpc.A2AServiceBlockingV2Stub;
1818
import io.a2a.grpc.A2AServiceGrpc.A2AServiceStub;
19-
import io.a2a.grpc.CancelTaskRequest;
20-
import io.a2a.grpc.CreateTaskPushNotificationConfigRequest;
21-
import io.a2a.grpc.DeleteTaskPushNotificationConfigRequest;
22-
import io.a2a.grpc.GetTaskPushNotificationConfigRequest;
23-
import io.a2a.grpc.GetTaskRequest;
24-
import io.a2a.grpc.ListTaskPushNotificationConfigRequest;
25-
import io.a2a.grpc.ListTasksRequest;
26-
import io.a2a.grpc.SendMessageRequest;
27-
import io.a2a.grpc.SendMessageResponse;
28-
import io.a2a.grpc.StreamResponse;
29-
import io.a2a.grpc.TaskSubscriptionRequest;
3019
import io.a2a.grpc.utils.ProtoUtils.FromProto;
3120
import io.a2a.grpc.utils.ProtoUtils.ToProto;
3221
import io.a2a.spec.A2AClientException;
3322
import io.a2a.spec.AgentCard;
23+
import io.a2a.spec.CancelTaskRequest;
3424
import io.a2a.spec.DeleteTaskPushNotificationConfigParams;
25+
import io.a2a.spec.DeleteTaskPushNotificationConfigRequest;
3526
import io.a2a.spec.EventKind;
3627
import io.a2a.spec.GetTaskPushNotificationConfigParams;
28+
import io.a2a.spec.GetTaskPushNotificationConfigRequest;
29+
import io.a2a.spec.GetTaskRequest;
3730
import io.a2a.spec.ListTaskPushNotificationConfigParams;
31+
import io.a2a.spec.ListTaskPushNotificationConfigRequest;
3832
import io.a2a.spec.ListTasksParams;
33+
import io.a2a.spec.ListTasksRequest;
3934
import io.a2a.spec.ListTasksResult;
4035
import io.a2a.spec.MessageSendParams;
36+
import io.a2a.spec.SendMessageRequest;
4137
import io.a2a.spec.SendStreamingMessageRequest;
4238
import io.a2a.spec.SetTaskPushNotificationConfigRequest;
4339
import io.a2a.spec.StreamingEventKind;
40+
import io.a2a.spec.SubscribeToTaskRequest;
4441
import io.a2a.spec.Task;
4542
import io.a2a.spec.TaskIdParams;
4643
import io.a2a.spec.TaskPushNotificationConfig;
4744
import io.a2a.spec.TaskQueryParams;
48-
import io.a2a.spec.TaskResubscriptionRequest;
4945
import io.grpc.Channel;
5046
import io.grpc.Metadata;
5147
import io.grpc.StatusRuntimeException;
@@ -83,13 +79,13 @@ public GrpcTransport(Channel channel, AgentCard agentCard, @Nullable List<Client
8379
public EventKind sendMessage(MessageSendParams request, @Nullable ClientCallContext context) throws A2AClientException {
8480
checkNotNullParam("request", request);
8581

86-
SendMessageRequest sendMessageRequest = createGrpcSendMessageRequest(request, context);
87-
PayloadAndHeaders payloadAndHeaders = applyInterceptors(io.a2a.spec.SendMessageRequest.METHOD, sendMessageRequest,
82+
io.a2a.grpc.SendMessageRequest sendMessageRequest = createGrpcSendMessageRequest(request, context);
83+
PayloadAndHeaders payloadAndHeaders = applyInterceptors(SendMessageRequest.METHOD, sendMessageRequest,
8884
agentCard, context);
8985

9086
try {
9187
A2AServiceBlockingV2Stub stubWithMetadata = createBlockingStubWithMetadata(context, payloadAndHeaders);
92-
SendMessageResponse response = stubWithMetadata.sendMessage(sendMessageRequest);
88+
io.a2a.grpc.SendMessageResponse response = stubWithMetadata.sendMessage(sendMessageRequest);
9389
if (response.hasMsg()) {
9490
return FromProto.message(response.getMsg());
9591
} else if (response.hasTask()) {
@@ -107,10 +103,10 @@ public void sendMessageStreaming(MessageSendParams request, Consumer<StreamingEv
107103
Consumer<Throwable> errorConsumer, @Nullable ClientCallContext context) throws A2AClientException {
108104
checkNotNullParam("request", request);
109105
checkNotNullParam("eventConsumer", eventConsumer);
110-
SendMessageRequest grpcRequest = createGrpcSendMessageRequest(request, context);
106+
io.a2a.grpc.SendMessageRequest grpcRequest = createGrpcSendMessageRequest(request, context);
111107
PayloadAndHeaders payloadAndHeaders = applyInterceptors(SendStreamingMessageRequest.METHOD,
112108
grpcRequest, agentCard, context);
113-
StreamObserver<StreamResponse> streamObserver = new EventStreamObserver(eventConsumer, errorConsumer);
109+
StreamObserver<io.a2a.grpc.StreamResponse> streamObserver = new EventStreamObserver(eventConsumer, errorConsumer);
114110

115111
try {
116112
A2AServiceStub stubWithMetadata = createAsyncStubWithMetadata(context, payloadAndHeaders);
@@ -124,11 +120,11 @@ public void sendMessageStreaming(MessageSendParams request, Consumer<StreamingEv
124120
public Task getTask(TaskQueryParams request, @Nullable ClientCallContext context) throws A2AClientException {
125121
checkNotNullParam("request", request);
126122

127-
GetTaskRequest.Builder requestBuilder = GetTaskRequest.newBuilder();
123+
io.a2a.grpc.GetTaskRequest.Builder requestBuilder = io.a2a.grpc.GetTaskRequest.newBuilder();
128124
requestBuilder.setName("tasks/" + request.id());
129125
requestBuilder.setHistoryLength(request.historyLength());
130-
GetTaskRequest getTaskRequest = requestBuilder.build();
131-
PayloadAndHeaders payloadAndHeaders = applyInterceptors(io.a2a.spec.GetTaskRequest.METHOD, getTaskRequest,
126+
io.a2a.grpc.GetTaskRequest getTaskRequest = requestBuilder.build();
127+
PayloadAndHeaders payloadAndHeaders = applyInterceptors(GetTaskRequest.METHOD, getTaskRequest,
132128
agentCard, context);
133129

134130
try {
@@ -143,10 +139,10 @@ public Task getTask(TaskQueryParams request, @Nullable ClientCallContext context
143139
public Task cancelTask(TaskIdParams request, @Nullable ClientCallContext context) throws A2AClientException {
144140
checkNotNullParam("request", request);
145141

146-
CancelTaskRequest cancelTaskRequest = CancelTaskRequest.newBuilder()
142+
io.a2a.grpc.CancelTaskRequest cancelTaskRequest = io.a2a.grpc.CancelTaskRequest.newBuilder()
147143
.setName("tasks/" + request.id())
148144
.build();
149-
PayloadAndHeaders payloadAndHeaders = applyInterceptors(io.a2a.spec.CancelTaskRequest.METHOD, cancelTaskRequest,
145+
PayloadAndHeaders payloadAndHeaders = applyInterceptors(CancelTaskRequest.METHOD, cancelTaskRequest,
150146
agentCard, context);
151147

152148
try {
@@ -161,35 +157,37 @@ public Task cancelTask(TaskIdParams request, @Nullable ClientCallContext context
161157
public ListTasksResult listTasks(ListTasksParams request, @Nullable ClientCallContext context) throws A2AClientException {
162158
checkNotNullParam("request", request);
163159

164-
ListTasksRequest.Builder requestBuilder = ListTasksRequest.newBuilder();
160+
io.a2a.grpc.ListTasksRequest.Builder builder = io.a2a.grpc.ListTasksRequest.newBuilder();
165161
if (request.contextId() != null) {
166-
requestBuilder.setContextId(request.contextId());
162+
builder.setContextId(request.contextId());
167163
}
168164
if (request.status() != null) {
169-
requestBuilder.setStatus(ToProto.taskState(request.status()));
165+
builder.setStatus(ToProto.taskState(request.status()));
170166
}
171167
if (request.pageSize() != null) {
172-
requestBuilder.setPageSize(request.pageSize());
168+
builder.setPageSize(request.pageSize());
173169
}
174170
if (request.pageToken() != null) {
175-
requestBuilder.setPageToken(request.pageToken());
171+
builder.setPageToken(request.pageToken());
176172
}
177173
if (request.historyLength() != null) {
178-
requestBuilder.setHistoryLength(request.historyLength());
174+
builder.setHistoryLength(request.historyLength());
179175
}
180-
if (request.includeArtifacts() != null && request.includeArtifacts()) {
181-
requestBuilder.setIncludeArtifacts(true);
176+
if (request.lastUpdatedAfter() != null) {
177+
builder.setLastUpdatedAfter(request.lastUpdatedAfter().toEpochMilli());
182178
}
183-
184-
ListTasksRequest listTasksRequest = requestBuilder.build();
185-
PayloadAndHeaders payloadAndHeaders = applyInterceptors(io.a2a.spec.ListTasksRequest.METHOD, listTasksRequest,
179+
if (request.includeArtifacts() != null) {
180+
builder.setIncludeArtifacts(request.includeArtifacts());
181+
}
182+
io.a2a.grpc.ListTasksRequest listTasksRequest = builder.build();
183+
PayloadAndHeaders payloadAndHeaders = applyInterceptors(ListTasksRequest.METHOD, listTasksRequest,
186184
agentCard, context);
187185

188186
try {
189187
A2AServiceBlockingV2Stub stubWithMetadata = createBlockingStubWithMetadata(context, payloadAndHeaders);
190188
io.a2a.grpc.ListTasksResponse grpcResponse = stubWithMetadata.listTasks(listTasksRequest);
191189

192-
return new io.a2a.spec.ListTasksResult(
190+
return new ListTasksResult(
193191
grpcResponse.getTasksList().stream()
194192
.map(FromProto::task)
195193
.collect(Collectors.toList()),
@@ -208,7 +206,7 @@ public TaskPushNotificationConfig setTaskPushNotificationConfiguration(TaskPushN
208206
checkNotNullParam("request", request);
209207

210208
String configId = request.pushNotificationConfig().id();
211-
CreateTaskPushNotificationConfigRequest grpcRequest = CreateTaskPushNotificationConfigRequest.newBuilder()
209+
io.a2a.grpc.SetTaskPushNotificationConfigRequest grpcRequest = io.a2a.grpc.SetTaskPushNotificationConfigRequest.newBuilder()
212210
.setParent("tasks/" + request.taskId())
213211
.setConfig(ToProto.taskPushNotificationConfig(request))
214212
.setConfigId(configId != null ? configId : request.taskId())
@@ -218,7 +216,7 @@ public TaskPushNotificationConfig setTaskPushNotificationConfiguration(TaskPushN
218216

219217
try {
220218
A2AServiceBlockingV2Stub stubWithMetadata = createBlockingStubWithMetadata(context, payloadAndHeaders);
221-
return FromProto.taskPushNotificationConfig(stubWithMetadata.createTaskPushNotificationConfig(grpcRequest));
219+
return FromProto.taskPushNotificationConfig(stubWithMetadata.setTaskPushNotificationConfig(grpcRequest));
222220
} catch (StatusRuntimeException e) {
223221
throw GrpcErrorMapper.mapGrpcError(e, "Failed to create task push notification config: ");
224222
}
@@ -230,10 +228,10 @@ public TaskPushNotificationConfig getTaskPushNotificationConfiguration(
230228
@Nullable ClientCallContext context) throws A2AClientException {
231229
checkNotNullParam("request", request);
232230

233-
GetTaskPushNotificationConfigRequest grpcRequest = GetTaskPushNotificationConfigRequest.newBuilder()
231+
io.a2a.grpc.GetTaskPushNotificationConfigRequest grpcRequest = io.a2a.grpc.GetTaskPushNotificationConfigRequest.newBuilder()
234232
.setName(getTaskPushNotificationConfigName(request))
235233
.build();
236-
PayloadAndHeaders payloadAndHeaders = applyInterceptors(io.a2a.spec.GetTaskPushNotificationConfigRequest.METHOD,
234+
PayloadAndHeaders payloadAndHeaders = applyInterceptors(GetTaskPushNotificationConfigRequest.METHOD,
237235
grpcRequest, agentCard, context);
238236

239237
try {
@@ -250,10 +248,10 @@ public List<TaskPushNotificationConfig> listTaskPushNotificationConfigurations(
250248
@Nullable ClientCallContext context) throws A2AClientException {
251249
checkNotNullParam("request", request);
252250

253-
ListTaskPushNotificationConfigRequest grpcRequest = ListTaskPushNotificationConfigRequest.newBuilder()
251+
io.a2a.grpc.ListTaskPushNotificationConfigRequest grpcRequest = io.a2a.grpc.ListTaskPushNotificationConfigRequest.newBuilder()
254252
.setParent("tasks/" + request.id())
255253
.build();
256-
PayloadAndHeaders payloadAndHeaders = applyInterceptors(io.a2a.spec.ListTaskPushNotificationConfigRequest.METHOD,
254+
PayloadAndHeaders payloadAndHeaders = applyInterceptors(ListTaskPushNotificationConfigRequest.METHOD,
257255
grpcRequest, agentCard, context);
258256

259257
try {
@@ -271,10 +269,10 @@ public void deleteTaskPushNotificationConfigurations(DeleteTaskPushNotificationC
271269
@Nullable ClientCallContext context) throws A2AClientException {
272270
checkNotNullParam("request", request);
273271

274-
DeleteTaskPushNotificationConfigRequest grpcRequest = DeleteTaskPushNotificationConfigRequest.newBuilder()
272+
io.a2a.grpc.DeleteTaskPushNotificationConfigRequest grpcRequest = io.a2a.grpc.DeleteTaskPushNotificationConfigRequest.newBuilder()
275273
.setName(getTaskPushNotificationConfigName(request.id(), request.pushNotificationConfigId()))
276274
.build();
277-
PayloadAndHeaders payloadAndHeaders = applyInterceptors(io.a2a.spec.DeleteTaskPushNotificationConfigRequest.METHOD,
275+
PayloadAndHeaders payloadAndHeaders = applyInterceptors(DeleteTaskPushNotificationConfigRequest.METHOD,
278276
grpcRequest, agentCard, context);
279277

280278
try {
@@ -291,17 +289,17 @@ public void resubscribe(TaskIdParams request, Consumer<StreamingEventKind> event
291289
checkNotNullParam("request", request);
292290
checkNotNullParam("eventConsumer", eventConsumer);
293291

294-
TaskSubscriptionRequest grpcRequest = TaskSubscriptionRequest.newBuilder()
292+
io.a2a.grpc.SubscribeToTaskRequest grpcRequest = io.a2a.grpc.SubscribeToTaskRequest.newBuilder()
295293
.setName("tasks/" + request.id())
296294
.build();
297-
PayloadAndHeaders payloadAndHeaders = applyInterceptors(TaskResubscriptionRequest.METHOD,
295+
PayloadAndHeaders payloadAndHeaders = applyInterceptors(SubscribeToTaskRequest.METHOD,
298296
grpcRequest, agentCard, context);
299297

300-
StreamObserver<StreamResponse> streamObserver = new EventStreamObserver(eventConsumer, errorConsumer);
298+
StreamObserver<io.a2a.grpc.StreamResponse> streamObserver = new EventStreamObserver(eventConsumer, errorConsumer);
301299

302300
try {
303301
A2AServiceStub stubWithMetadata = createAsyncStubWithMetadata(context, payloadAndHeaders);
304-
stubWithMetadata.taskSubscription(grpcRequest, streamObserver);
302+
stubWithMetadata.subscribeToTask(grpcRequest, streamObserver);
305303
} catch (StatusRuntimeException e) {
306304
throw GrpcErrorMapper.mapGrpcError(e, "Failed to resubscribe task push notification config: ");
307305
}
@@ -317,16 +315,8 @@ public AgentCard getAgentCard(@Nullable ClientCallContext context) throws A2ACli
317315
public void close() {
318316
}
319317

320-
private SendMessageRequest createGrpcSendMessageRequest(MessageSendParams messageSendParams, @Nullable ClientCallContext context) {
321-
SendMessageRequest.Builder builder = SendMessageRequest.newBuilder();
322-
builder.setRequest(ToProto.message(messageSendParams.message()));
323-
if (messageSendParams.configuration() != null) {
324-
builder.setConfiguration(ToProto.messageSendConfiguration(messageSendParams.configuration()));
325-
}
326-
if (messageSendParams.metadata() != null) {
327-
builder.setMetadata(ToProto.struct(messageSendParams.metadata()));
328-
}
329-
return builder.build();
318+
private io.a2a.grpc.SendMessageRequest createGrpcSendMessageRequest(MessageSendParams messageSendParams, @Nullable ClientCallContext context) {
319+
return ToProto.sendMessageRequest(messageSendParams);
330320
}
331321

332322
/**

0 commit comments

Comments
 (0)