Skip to content

Commit a05627e

Browse files
committed
feat!: Upgrading to latest a2a.proto
* Generating new grpc specifications * Updating code impacted by those changes * Removing some unused metadata Signed-off-by: Emmanuel Hugonnet <[email protected]>
1 parent ec0ef92 commit a05627e

File tree

147 files changed

+3816
-1628
lines changed

Some content is hidden

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

147 files changed

+3816
-1628
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,11 @@ public Task getTask(TaskQueryParams request, @Nullable ClientCallContext context
123123

124124
io.a2a.grpc.GetTaskRequest.Builder requestBuilder = io.a2a.grpc.GetTaskRequest.newBuilder();
125125
requestBuilder.setName("tasks/" + request.id());
126-
requestBuilder.setHistoryLength(request.historyLength());
126+
if(request.historyLength() != null) {
127+
requestBuilder.setHistoryLength(request.historyLength());
128+
} else {
129+
requestBuilder.clearHistoryLength();
130+
}
127131
io.a2a.grpc.GetTaskRequest getTaskRequest = requestBuilder.build();
128132
PayloadAndHeaders payloadAndHeaders = applyInterceptors(GetTaskRequest.METHOD, getTaskRequest,
129133
agentCard, context);
@@ -218,7 +222,7 @@ public TaskPushNotificationConfig setTaskPushNotificationConfiguration(TaskPushN
218222
try {
219223
A2AServiceBlockingV2Stub stubWithMetadata = createBlockingStubWithMetadata(context, payloadAndHeaders);
220224
return FromProto.taskPushNotificationConfig(stubWithMetadata.setTaskPushNotificationConfig(grpcRequest));
221-
} catch (StatusRuntimeException e) {
225+
} catch (StatusRuntimeException | StatusException e) {
222226
throw GrpcErrorMapper.mapGrpcError(e, "Failed to create task push notification config: ");
223227
}
224228
}

client/transport/jsonrpc/src/main/java/io/a2a/client/transport/jsonrpc/JSONRPCTransport.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public JSONRPCTransport(@Nullable A2AHttpClient httpClient, @Nullable AgentCard
8585
this.agentCard = agentCard;
8686
this.agentUrl = agentUrl;
8787
this.interceptors = interceptors;
88-
this.needsExtendedCard = agentCard == null || agentCard.supportsAuthenticatedExtendedCard();
88+
this.needsExtendedCard = agentCard == null || agentCard.supportsExtendedAgentCard();
8989
}
9090

9191
@Override
@@ -295,7 +295,7 @@ public AgentCard getAgentCard(@Nullable ClientCallContext context) throws A2ACli
295295
if (agentCard == null) {
296296
resolver = new A2ACardResolver(httpClient, agentUrl, null, getHttpHeaders(context));
297297
agentCard = resolver.getAgentCard();
298-
needsExtendedCard = agentCard.supportsAuthenticatedExtendedCard();
298+
needsExtendedCard = agentCard.supportsExtendedAgentCard();
299299
}
300300
if (!needsExtendedCard) {
301301
return agentCard;

client/transport/jsonrpc/src/test/java/io/a2a/client/transport/jsonrpc/JSONRPCTransportTest.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,7 @@ public void testA2AClientCancelTask() throws Exception {
286286
);
287287

288288
JSONRPCTransport client = new JSONRPCTransport("http://localhost:4001");
289-
Task task = client.cancelTask(new TaskIdParams("de38c76d-d54c-436c-8b9f-4c2703648d64",
290-
new HashMap<>()), null);
289+
Task task = client.cancelTask(new TaskIdParams("de38c76d-d54c-436c-8b9f-4c2703648d64"), null);
291290
assertEquals("de38c76d-d54c-436c-8b9f-4c2703648d64", task.getId());
292291
assertEquals("c295ea44-7543-4f78-b524-7a38915ad6e4", task.getContextId());
293292
assertEquals(TaskState.CANCELED, task.getStatus().state());
@@ -311,8 +310,7 @@ public void testA2AClientGetTaskPushNotificationConfig() throws Exception {
311310

312311
JSONRPCTransport client = new JSONRPCTransport("http://localhost:4001");
313312
TaskPushNotificationConfig taskPushNotificationConfig = client.getTaskPushNotificationConfiguration(
314-
new GetTaskPushNotificationConfigParams("de38c76d-d54c-436c-8b9f-4c2703648d64", "c295ea44-7543-4f78-b524-7a38915ad6e4",
315-
new HashMap<>()), null);
313+
new GetTaskPushNotificationConfigParams("de38c76d-d54c-436c-8b9f-4c2703648d64", "c295ea44-7543-4f78-b524-7a38915ad6e4"), null);
316314
PushNotificationConfig pushNotificationConfig = taskPushNotificationConfig.pushNotificationConfig();
317315
assertNotNull(pushNotificationConfig);
318316
assertEquals("https://example.com/callback", pushNotificationConfig.url());
@@ -344,7 +342,7 @@ public void testA2AClientSetTaskPushNotificationConfig() throws Exception {
344342
.url("https://example.com/callback")
345343
.authenticationInfo(new AuthenticationInfo(Collections.singletonList("jwt"),
346344
null))
347-
.build()), null);
345+
.build(), "tenant"), null);
348346
PushNotificationConfig pushNotificationConfig = taskPushNotificationConfig.pushNotificationConfig();
349347
assertNotNull(pushNotificationConfig);
350348
assertEquals("https://example.com/callback", pushNotificationConfig.url());
@@ -418,7 +416,7 @@ public void testA2AClientGetAgentCard() throws Exception {
418416
assertEquals(inputModes, skills.get(1).inputModes());
419417
outputModes = List.of("image/png", "image/jpeg", "application/json", "text/html");
420418
assertEquals(outputModes, skills.get(1).outputModes());
421-
assertFalse(agentCard.supportsAuthenticatedExtendedCard());
419+
assertFalse(agentCard.supportsExtendedAgentCard());
422420
assertEquals("https://georoute-agent.example.com/icon.png", agentCard.iconUrl());
423421
assertEquals("0.2.9", agentCard.protocolVersion());
424422
assertEquals("JSONRPC", agentCard.supportedInterfaces().get(0).protocolBinding());
@@ -511,7 +509,7 @@ public void testA2AClientGetAuthenticatedExtendedAgentCard() throws Exception {
511509
assertEquals("Extended Skill", skills.get(2).name());
512510
assertEquals("This is an extended skill.", skills.get(2).description());
513511
assertEquals(List.of("extended"), skills.get(2).tags());
514-
assertTrue(agentCard.supportsAuthenticatedExtendedCard());
512+
assertTrue(agentCard.supportsExtendedAgentCard());
515513
assertEquals("https://georoute-agent.example.com/icon.png", agentCard.iconUrl());
516514
assertEquals("0.2.5", agentCard.protocolVersion());
517515
}

client/transport/jsonrpc/src/test/java/io/a2a/client/transport/jsonrpc/JsonMessages.java

Lines changed: 7 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ public class JsonMessages {
1212
"name": "GeoSpatial Route Planner Agent",
1313
"description": "Provides advanced route planning, traffic analysis, and custom map generation services. This agent can calculate optimal routes, estimate travel times considering real-time traffic, and create personalized maps with points of interest.",
1414
"supportedInterfaces" : [
15-
{"url": "https://georoute-agent.example.com/a2a/v1", "protocolBinding": "JSONRPC"},
16-
{"url": "https://georoute-agent.example.com/a2a/grpc", "protocolBinding": "GRPC"},
17-
{"url": "https://georoute-agent.example.com/a2a/json", "protocolBinding": "HTTP+JSON"}
15+
{"url": "https://georoute-agent.example.com/a2a/v1", "protocolBinding": "JSONRPC", tenant=""},
16+
{"url": "https://georoute-agent.example.com/a2a/grpc", "protocolBinding": "GRPC", tenant=""},
17+
{"url": "https://georoute-agent.example.com/a2a/json", "protocolBinding": "HTTP+JSON", tenant=""}
1818
],
1919
"provider": {
2020
"organization": "Example Geo Services Inc.",
@@ -73,7 +73,7 @@ public class JsonMessages {
7373
]
7474
}
7575
],
76-
"supportsAuthenticatedExtendedCard": false,
76+
"supportsExtendedAgentCard": false,
7777
"signatures": [
7878
{
7979
"protected": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpPU0UiLCJraWQiOiJrZXktMSIsImprdSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vYWdlbnQvandrcy5qc29uIn0",
@@ -82,86 +82,6 @@ public class JsonMessages {
8282
]
8383
}""";
8484

85-
static final String AUTHENTICATION_EXTENDED_AGENT_CARD = """
86-
{
87-
"name": "GeoSpatial Route Planner Agent Extended",
88-
"description": "Extended description",
89-
"supportedInterfaces": [
90-
{"url": "https://georoute-agent.example.com/a2a/v1", "protocolBinding": "JSONRPC"}
91-
],
92-
"provider": {
93-
"organization": "Example Geo Services Inc.",
94-
"url": "https://www.examplegeoservices.com"
95-
},
96-
"iconUrl": "https://georoute-agent.example.com/icon.png",
97-
"version": "1.2.0",
98-
"documentationUrl": "https://docs.examplegeoservices.com/georoute-agent/api",
99-
"capabilities": {
100-
"streaming": true,
101-
"pushNotifications": true,
102-
"stateTransitionHistory": false
103-
},
104-
"securitySchemes": {
105-
"google": {
106-
"openIdConnectSecurityScheme": {
107-
"openIdConnectUrl": "https://accounts.google.com/.well-known/openid-configuration"
108-
}
109-
}
110-
},
111-
"security": [{ "schemes": { "google": { "list": ["openid", "profile", "email"] } } }],
112-
"defaultInputModes": ["application/json", "text/plain"],
113-
"defaultOutputModes": ["application/json", "image/png"],
114-
"skills": [
115-
{
116-
"id": "route-optimizer-traffic",
117-
"name": "Traffic-Aware Route Optimizer",
118-
"description": "Calculates the optimal driving route between two or more locations, taking into account real-time traffic conditions, road closures, and user preferences (e.g., avoid tolls, prefer highways).",
119-
"tags": ["maps", "routing", "navigation", "directions", "traffic"],
120-
"examples": [
121-
"Plan a route from '1600 Amphitheatre Parkway, Mountain View, CA' to 'San Francisco International Airport' avoiding tolls.",
122-
"{\\"origin\\": {\\"lat\\": 37.422, \\"lng\\": -122.084}, \\"destination\\": {\\"lat\\": 37.7749, \\"lng\\": -122.4194}, \\"preferences\\": [\\"avoid_ferries\\"]}"
123-
],
124-
"inputModes": ["application/json", "text/plain"],
125-
"outputModes": [
126-
"application/json",
127-
"application/vnd.geo+json",
128-
"text/html"
129-
]
130-
},
131-
{
132-
"id": "custom-map-generator",
133-
"name": "Personalized Map Generator",
134-
"description": "Creates custom map images or interactive map views based on user-defined points of interest, routes, and style preferences. Can overlay data layers.",
135-
"tags": ["maps", "customization", "visualization", "cartography"],
136-
"examples": [
137-
"Generate a map of my upcoming road trip with all planned stops highlighted.",
138-
"Show me a map visualizing all coffee shops within a 1-mile radius of my current location."
139-
],
140-
"inputModes": ["application/json"],
141-
"outputModes": [
142-
"image/png",
143-
"image/jpeg",
144-
"application/json",
145-
"text/html"
146-
]
147-
},
148-
{
149-
"id": "skill-extended",
150-
"name": "Extended Skill",
151-
"description": "This is an extended skill.",
152-
"tags": ["extended"]
153-
}
154-
],
155-
"supportsAuthenticatedExtendedCard": true,
156-
"protocolVersion": "0.2.9",
157-
"signatures": [
158-
{
159-
"protected": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpPU0UiLCJraWQiOiJrZXktMSIsImprdSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vYWdlbnQvandrcy5qc29uIn0",
160-
"signature": "QFdkNLNszlGj3z3u0YQGt_T9LixY3qtdQpZmsTdDHDe3fXV9y9-B3m2-XgCpzuhiLt8E0tV6HXoZKHv4GtHgKQ"
161-
}
162-
]
163-
}""";
164-
16585
static final String SEND_MESSAGE_TEST_REQUEST = """
16686
{
16787
"jsonrpc":"2.0",
@@ -676,7 +596,7 @@ public class JsonMessages {
676596
"name": "GeoSpatial Route Planner Agent Extended",
677597
"description": "Extended description",
678598
"supportedInterfaces": [
679-
{"url": "https://georoute-agent.example.com/a2a/v1", "protocolBinding": "JSONRPC"}
599+
{"url": "https://georoute-agent.example.com/a2a/v1", "protocolBinding": "JSONRPC", "tenant": ""}
680600
],
681601
"provider": {
682602
"organization": "Example Geo Services Inc.",
@@ -741,7 +661,7 @@ public class JsonMessages {
741661
"tags": ["extended"]
742662
}
743663
],
744-
"supportsAuthenticatedExtendedCard": true,
664+
"supportsExtendedAgentCard": true,
745665
"protocolVersion": "0.2.5",
746666
"signatures": [
747667
{
@@ -816,7 +736,7 @@ public class JsonMessages {
816736
]
817737
}
818738
],
819-
"supportsAuthenticatedExtendedCard": true,
739+
"supportsExtendedAgentCard": true,
820740
"protocolVersion": "1.0.0"
821741
}""";
822742
}

client/transport/rest/src/main/java/io/a2a/client/transport/rest/RestTransport.java

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public Task getTask(TaskQueryParams taskQueryParams, @Nullable ClientCallContext
136136
agentCard, context);
137137
try {
138138
String url;
139-
if (taskQueryParams.historyLength() > 0) {
139+
if (taskQueryParams.historyLength() != null && taskQueryParams.historyLength() > 0) {
140140
url = agentUrl + String.format("/v1/tasks/%1s?historyLength=%2d", taskQueryParams.id(), taskQueryParams.historyLength());
141141
} else {
142142
url = agentUrl + String.format("/v1/tasks/%1s", taskQueryParams.id());
@@ -200,6 +200,9 @@ public ListTasksResult listTasks(ListTasksParams request, @Nullable ClientCallCo
200200
if (request.historyLength() != null) {
201201
builder.setHistoryLength(request.historyLength());
202202
}
203+
if (request.tenant() != null) {
204+
builder.setTenant(request.tenant());
205+
}
203206
if (request.includeArtifacts() != null && request.includeArtifacts()) {
204207
builder.setIncludeArtifacts(true);
205208
}
@@ -209,7 +212,11 @@ public ListTasksResult listTasks(ListTasksParams request, @Nullable ClientCallCo
209212

210213
try {
211214
// Build query string
212-
StringBuilder urlBuilder = new StringBuilder(agentUrl).append("/v1/tasks");
215+
StringBuilder urlBuilder = new StringBuilder(agentUrl);
216+
// if (request.tenant() != null && !request.tenant().isBlank()) {
217+
// urlBuilder.append('/').append(request.tenant());
218+
// }
219+
urlBuilder.append("/v1/tasks");
213220
String queryParams = buildListTasksQueryString(request);
214221
if (!queryParams.isEmpty()) {
215222
urlBuilder.append("?").append(queryParams);
@@ -268,8 +275,8 @@ private String buildListTasksQueryString(ListTasksParams request) {
268275
@Override
269276
public TaskPushNotificationConfig setTaskPushNotificationConfiguration(TaskPushNotificationConfig request, @Nullable ClientCallContext context) throws A2AClientException {
270277
checkNotNullParam("request", request);
271-
io.a2a.grpc.SetTaskPushNotificationConfigRequest.Builder builder =
272-
io.a2a.grpc.SetTaskPushNotificationConfigRequest.newBuilder();
278+
io.a2a.grpc.SetTaskPushNotificationConfigRequest.Builder builder
279+
= io.a2a.grpc.SetTaskPushNotificationConfigRequest.newBuilder();
273280
builder.setConfig(ProtoUtils.ToProto.taskPushNotificationConfig(request))
274281
.setParent("tasks/" + request.taskId());
275282
if (request.pushNotificationConfig().id() != null) {
@@ -291,8 +298,8 @@ public TaskPushNotificationConfig setTaskPushNotificationConfiguration(TaskPushN
291298
@Override
292299
public TaskPushNotificationConfig getTaskPushNotificationConfiguration(GetTaskPushNotificationConfigParams request, @Nullable ClientCallContext context) throws A2AClientException {
293300
checkNotNullParam("request", request);
294-
io.a2a.grpc.GetTaskPushNotificationConfigRequest.Builder builder =
295-
io.a2a.grpc.GetTaskPushNotificationConfigRequest.newBuilder();
301+
io.a2a.grpc.GetTaskPushNotificationConfigRequest.Builder builder
302+
= io.a2a.grpc.GetTaskPushNotificationConfigRequest.newBuilder();
296303
builder.setName(String.format("/tasks/%1s/pushNotificationConfigs/%2s", request.id(), request.pushNotificationConfigId()));
297304
PayloadAndHeaders payloadAndHeaders = applyInterceptors(GetTaskPushNotificationConfigRequest.METHOD, builder,
298305
agentCard, context);
@@ -322,8 +329,8 @@ public TaskPushNotificationConfig getTaskPushNotificationConfiguration(GetTaskPu
322329
@Override
323330
public List<TaskPushNotificationConfig> listTaskPushNotificationConfigurations(ListTaskPushNotificationConfigParams request, @Nullable ClientCallContext context) throws A2AClientException {
324331
checkNotNullParam("request", request);
325-
io.a2a.grpc.ListTaskPushNotificationConfigRequest.Builder builder =
326-
io.a2a.grpc.ListTaskPushNotificationConfigRequest.newBuilder();
332+
io.a2a.grpc.ListTaskPushNotificationConfigRequest.Builder builder
333+
= io.a2a.grpc.ListTaskPushNotificationConfigRequest.newBuilder();
327334
builder.setParent(String.format("/tasks/%1s/pushNotificationConfigs", request.id()));
328335
PayloadAndHeaders payloadAndHeaders = applyInterceptors(ListTaskPushNotificationConfigRequest.METHOD, builder,
329336
agentCard, context);
@@ -410,7 +417,7 @@ public AgentCard getAgentCard(@Nullable ClientCallContext context) throws A2ACli
410417
if (agentCard == null) {
411418
resolver = new A2ACardResolver(httpClient, agentUrl, null, getHttpHeaders(context));
412419
agentCard = resolver.getAgentCard();
413-
needsExtendedCard = agentCard.supportsAuthenticatedExtendedCard();
420+
needsExtendedCard = agentCard.supportsExtendedAgentCard();
414421
}
415422
if (!needsExtendedCard) {
416423
return agentCard;

client/transport/rest/src/test/java/io/a2a/client/transport/rest/JsonRestMessages.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ public class JsonRestMessages {
168168
]
169169
}
170170
],
171-
"supportsAuthenticatedExtendedCard": false,
171+
"supportsExtendedAgentCard": false,
172172
"protocolVersion": "0.2.5"
173173
}""";
174174

@@ -235,7 +235,7 @@ public class JsonRestMessages {
235235
]
236236
}
237237
],
238-
"supportsAuthenticatedExtendedCard": true,
238+
"supportsExtendedAgentCard": true,
239239
"protocolVersion": "0.2.5"
240240
}""";
241241

@@ -308,7 +308,7 @@ public class JsonRestMessages {
308308
"tags": ["extended"]
309309
}
310310
],
311-
"supportsAuthenticatedExtendedCard": true,
311+
"supportsExtendedAgentCard": true,
312312
"protocolVersion": "0.2.5"
313313
}""";
314314

0 commit comments

Comments
 (0)