diff --git a/client/base/src/main/java/io/a2a/client/AbstractClient.java b/client/base/src/main/java/io/a2a/client/AbstractClient.java
index c3c8c648f..ae0d9b40b 100644
--- a/client/base/src/main/java/io/a2a/client/AbstractClient.java
+++ b/client/base/src/main/java/io/a2a/client/AbstractClient.java
@@ -390,17 +390,41 @@ public abstract void subscribeToTask(@NonNull TaskIdParams request,
* @throws A2AClientException if retrieving the extended agent card fails for any reason
*/
public AgentCard getExtendedAgentCard() throws A2AClientException {
- return getExtendedAgentCard(null);
+ return getExtendedAgentCard(null, null);
}
/**
* Retrieve the extended AgentCard.
*
+ * @param tenant Optional tenant
+ * @return the extended AgentCard
+ * @throws A2AClientException if retrieving the extended agent card fails for any reason
+ */
+ public AgentCard getExtendedAgentCard(@Nullable String tenant) throws A2AClientException {
+ return getExtendedAgentCard(tenant, null);
+ }
+
+ /**
+ * Retrieve the extended AgentCard.
+ *
+ * @param context optional client call context for the request (may be {@code null})
+ * @return the extended AgentCard
+ * @throws A2AClientException if retrieving the extended agent card fails for any reason
+ */
+ public AgentCard getExtendedAgentCard(@Nullable ClientCallContext context) throws A2AClientException {
+ return getExtendedAgentCard(null, context);
+ }
+
+ /**
+ * Retrieve the extended AgentCard.
+ *
+ * @param tenant Optional tenant
* @param context optional client call context for the request (may be {@code null})
* @return the extended AgentCard
* @throws A2AClientException if retrieving the extended agent card fails for any reason
*/
- public abstract AgentCard getExtendedAgentCard(@Nullable ClientCallContext context) throws A2AClientException;
+ public abstract AgentCard getExtendedAgentCard(@Nullable String tenant,
+ @Nullable ClientCallContext context) throws A2AClientException;
/**
* Close the transport and release any associated resources.
diff --git a/client/base/src/main/java/io/a2a/client/Client.java b/client/base/src/main/java/io/a2a/client/Client.java
index e60cac4e5..a603a8515 100644
--- a/client/base/src/main/java/io/a2a/client/Client.java
+++ b/client/base/src/main/java/io/a2a/client/Client.java
@@ -17,6 +17,7 @@
import io.a2a.spec.AgentCard;
import io.a2a.spec.DeleteTaskPushNotificationConfigParams;
import io.a2a.spec.EventKind;
+import io.a2a.spec.GetExtendedAgentCardParams;
import io.a2a.spec.GetTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
@@ -601,19 +602,21 @@ public void subscribeToTask(@NonNull TaskIdParams request,
*
* Example:
*
{@code
- * AgentCard updatedCard = client.getExtendedAgentCard(null);
+ * AgentCard updatedCard = client.getExtendedAgentCard();
* System.out.println("Agent version: " + updatedCard.version());
* System.out.println("Skills: " + updatedCard.skills().size());
* }
*
+ * @param tenant Optional tenant
* @param context custom call context for request interceptors (optional)
* @return the agent's extended agent card
* @throws A2AClientException if the extended agent card cannot be retrieved
* @see AgentCard
*/
@Override
- public AgentCard getExtendedAgentCard(@Nullable ClientCallContext context) throws A2AClientException {
- agentCard = clientTransport.getExtendedAgentCard(context);
+ public AgentCard getExtendedAgentCard(@Nullable String tenant, @Nullable ClientCallContext context) throws A2AClientException {
+ GetExtendedAgentCardParams params = new GetExtendedAgentCardParams(tenant);
+ agentCard = clientTransport.getExtendedAgentCard(params, context);
return agentCard;
}
diff --git a/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransport.java b/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransport.java
index 7824e83c0..cd8fa67a9 100644
--- a/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransport.java
+++ b/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransport.java
@@ -35,6 +35,7 @@
import io.a2a.spec.AgentCard;
import io.a2a.spec.DeleteTaskPushNotificationConfigParams;
import io.a2a.spec.EventKind;
+import io.a2a.spec.GetExtendedAgentCardParams;
import io.a2a.spec.GetTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
@@ -356,9 +357,12 @@ private MessageSendParams createRequestWithTenant(MessageSendParams request) {
}
@Override
- public AgentCard getExtendedAgentCard(@Nullable ClientCallContext context) throws A2AClientException {
- GetExtendedAgentCardRequest request = GetExtendedAgentCardRequest.newBuilder()
- .build();
+ public AgentCard getExtendedAgentCard(GetExtendedAgentCardParams params, @Nullable ClientCallContext context) throws A2AClientException {
+ GetExtendedAgentCardRequest.Builder builder = GetExtendedAgentCardRequest.newBuilder();
+ if (params.tenant() != null) {
+ builder.setTenant(params.tenant());
+ }
+ GetExtendedAgentCardRequest request = builder.build();
PayloadAndHeaders payloadAndHeaders = applyInterceptors(GET_EXTENDED_AGENT_CARD_METHOD, request, agentCard, context);
try {
diff --git a/client/transport/jsonrpc/src/main/java/io/a2a/client/transport/jsonrpc/JSONRPCTransport.java b/client/transport/jsonrpc/src/main/java/io/a2a/client/transport/jsonrpc/JSONRPCTransport.java
index 9b8af4ea2..a26600fe3 100644
--- a/client/transport/jsonrpc/src/main/java/io/a2a/client/transport/jsonrpc/JSONRPCTransport.java
+++ b/client/transport/jsonrpc/src/main/java/io/a2a/client/transport/jsonrpc/JSONRPCTransport.java
@@ -51,6 +51,7 @@
import io.a2a.spec.AgentInterface;
import io.a2a.spec.DeleteTaskPushNotificationConfigParams;
import io.a2a.spec.EventKind;
+import io.a2a.spec.GetExtendedAgentCardParams;
import io.a2a.spec.GetTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
@@ -284,13 +285,13 @@ public void subscribeToTask(TaskIdParams request, Consumer e
}
@Override
- public AgentCard getExtendedAgentCard(@Nullable ClientCallContext context) throws A2AClientException {
+ public AgentCard getExtendedAgentCard(GetExtendedAgentCardParams params, @Nullable ClientCallContext context) throws A2AClientException {
try {
PayloadAndHeaders payloadAndHeaders = applyInterceptors(GET_EXTENDED_AGENT_CARD_METHOD,
- ProtoUtils.ToProto.extendedAgentCard(), agentCard, context);
+ ProtoUtils.ToProto.extendedAgentCard(params), agentCard, context);
try {
- String httpResponseBody = sendPostRequest(Utils.buildBaseUrl(agentInterface, ""), payloadAndHeaders, GET_EXTENDED_AGENT_CARD_METHOD);
+ String httpResponseBody = sendPostRequest(Utils.buildBaseUrl(agentInterface, params.tenant()), payloadAndHeaders, GET_EXTENDED_AGENT_CARD_METHOD);
GetExtendedAgentCardResponse response = unmarshalResponse(httpResponseBody, GET_EXTENDED_AGENT_CARD_METHOD);
return response.getResult();
} catch (IOException | InterruptedException | JsonProcessingException e) {
diff --git a/client/transport/jsonrpc/src/test/java/io/a2a/client/transport/jsonrpc/JSONRPCTransportTest.java b/client/transport/jsonrpc/src/test/java/io/a2a/client/transport/jsonrpc/JSONRPCTransportTest.java
index e4983142b..a5fa5d813 100644
--- a/client/transport/jsonrpc/src/test/java/io/a2a/client/transport/jsonrpc/JSONRPCTransportTest.java
+++ b/client/transport/jsonrpc/src/test/java/io/a2a/client/transport/jsonrpc/JSONRPCTransportTest.java
@@ -50,6 +50,7 @@
import io.a2a.spec.FilePart;
import io.a2a.spec.FileWithBytes;
import io.a2a.spec.FileWithUri;
+import io.a2a.spec.GetExtendedAgentCardParams;
import io.a2a.spec.GetTaskPushNotificationConfigParams;
import io.a2a.spec.Message;
import io.a2a.spec.MessageSendConfiguration;
@@ -361,7 +362,8 @@ public void testA2AClientGetExtendedAgentCard() throws Exception {
);
JSONRPCTransport client = new JSONRPCTransport("http://localhost:4001");
- AgentCard agentCard = client.getExtendedAgentCard(null);
+ GetExtendedAgentCardParams params = new GetExtendedAgentCardParams(null);
+ AgentCard agentCard = client.getExtendedAgentCard(params, null);
assertEquals("GeoSpatial Route Planner Agent Extended", agentCard.name());
assertEquals("Extended description", agentCard.description());
assertEquals("https://georoute-agent.example.com/a2a/v1", Utils.getFavoriteInterface(agentCard).url());
diff --git a/client/transport/rest/src/main/java/io/a2a/client/transport/rest/RestTransport.java b/client/transport/rest/src/main/java/io/a2a/client/transport/rest/RestTransport.java
index 09e68b88a..0e3c95d6b 100644
--- a/client/transport/rest/src/main/java/io/a2a/client/transport/rest/RestTransport.java
+++ b/client/transport/rest/src/main/java/io/a2a/client/transport/rest/RestTransport.java
@@ -45,6 +45,7 @@
import io.a2a.spec.AgentInterface;
import io.a2a.spec.DeleteTaskPushNotificationConfigParams;
import io.a2a.spec.EventKind;
+import io.a2a.spec.GetExtendedAgentCardParams;
import io.a2a.spec.GetTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
@@ -414,15 +415,13 @@ public void subscribeToTask(TaskIdParams request, Consumer e
}
@Override
- public AgentCard getExtendedAgentCard(@Nullable ClientCallContext context) throws A2AClientException {
+ public AgentCard getExtendedAgentCard(GetExtendedAgentCardParams params, @Nullable ClientCallContext context) throws A2AClientException {
try {
PayloadAndHeaders payloadAndHeaders = applyInterceptors(GET_EXTENDED_AGENT_CARD_METHOD, null, agentCard, context);
- String url = Utils.buildBaseUrl(agentInterface, "") + "/extendedAgentCard";
+ String url = Utils.buildBaseUrl(agentInterface, params.tenant()) + "/extendedAgentCard";
A2AHttpClient.GetBuilder getBuilder = httpClient.createGet().url(url);
- if (payloadAndHeaders.getHeaders() != null) {
- for (Map.Entry entry : payloadAndHeaders.getHeaders().entrySet()) {
+ for (Map.Entry entry : payloadAndHeaders.getHeaders().entrySet()) {
getBuilder.addHeader(entry.getKey(), entry.getValue());
- }
}
A2AHttpResponse response = getBuilder.get();
if (!response.success()) {
diff --git a/client/transport/spi/src/main/java/io/a2a/client/transport/spi/ClientTransport.java b/client/transport/spi/src/main/java/io/a2a/client/transport/spi/ClientTransport.java
index 82fe40996..3ecad6019 100644
--- a/client/transport/spi/src/main/java/io/a2a/client/transport/spi/ClientTransport.java
+++ b/client/transport/spi/src/main/java/io/a2a/client/transport/spi/ClientTransport.java
@@ -8,6 +8,7 @@
import io.a2a.spec.AgentCard;
import io.a2a.spec.DeleteTaskPushNotificationConfigParams;
import io.a2a.spec.EventKind;
+import io.a2a.spec.GetExtendedAgentCardParams;
import io.a2a.spec.GetTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
@@ -139,11 +140,12 @@ void subscribeToTask(TaskIdParams request, Consumer eventCon
/**
* Retrieve the extended AgentCard.
*
+ * @param params the parameters to get the extended agent card.
* @param context optional client call context for the request (may be {@code null})
* @return the extended agent card
* @throws A2AClientException if retrieving the agent card fails for any reason
*/
- AgentCard getExtendedAgentCard(@Nullable ClientCallContext context) throws A2AClientException;
+ AgentCard getExtendedAgentCard(GetExtendedAgentCardParams params, @Nullable ClientCallContext context) throws A2AClientException;
/**
* Close the transport and release any associated resources.
diff --git a/extras/opentelemetry/client-propagation/src/main/java/io/a2a/extras/opentelemetry/client/propagation/OpenTelemetryClientPropagatorTransport.java b/extras/opentelemetry/client-propagation/src/main/java/io/a2a/extras/opentelemetry/client/propagation/OpenTelemetryClientPropagatorTransport.java
index 53cd134bd..52854d3ef 100644
--- a/extras/opentelemetry/client-propagation/src/main/java/io/a2a/extras/opentelemetry/client/propagation/OpenTelemetryClientPropagatorTransport.java
+++ b/extras/opentelemetry/client-propagation/src/main/java/io/a2a/extras/opentelemetry/client/propagation/OpenTelemetryClientPropagatorTransport.java
@@ -7,6 +7,7 @@
import io.a2a.spec.AgentCard;
import io.a2a.spec.DeleteTaskPushNotificationConfigParams;
import io.a2a.spec.EventKind;
+import io.a2a.spec.GetExtendedAgentCardParams;
import io.a2a.spec.GetTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
@@ -112,8 +113,8 @@ public void subscribeToTask(TaskIdParams request, Consumer e
}
@Override
- public AgentCard getExtendedAgentCard(@Nullable ClientCallContext context) throws A2AClientException {
- return delegate.getExtendedAgentCard(propagateContext(context));
+ public AgentCard getExtendedAgentCard(GetExtendedAgentCardParams request, @Nullable ClientCallContext context) throws A2AClientException {
+ return delegate.getExtendedAgentCard(request, propagateContext(context));
}
@Override
diff --git a/extras/opentelemetry/client/src/main/java/io/a2a/extras/opentelemetry/client/OpenTelemetryClientTransport.java b/extras/opentelemetry/client/src/main/java/io/a2a/extras/opentelemetry/client/OpenTelemetryClientTransport.java
index ed0db190d..98627c258 100644
--- a/extras/opentelemetry/client/src/main/java/io/a2a/extras/opentelemetry/client/OpenTelemetryClientTransport.java
+++ b/extras/opentelemetry/client/src/main/java/io/a2a/extras/opentelemetry/client/OpenTelemetryClientTransport.java
@@ -21,6 +21,7 @@
import io.a2a.spec.AgentCard;
import io.a2a.spec.DeleteTaskPushNotificationConfigParams;
import io.a2a.spec.EventKind;
+import io.a2a.spec.GetExtendedAgentCardParams;
import io.a2a.spec.GetTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
@@ -393,13 +394,13 @@ public void subscribeToTask(TaskIdParams request, Consumer e
}
@Override
- public AgentCard getExtendedAgentCard(@Nullable ClientCallContext context) throws A2AClientException {
+ public AgentCard getExtendedAgentCard(GetExtendedAgentCardParams params, @Nullable ClientCallContext context) throws A2AClientException {
ClientCallContext clientContext = createContext(context);
SpanBuilder spanBuilder = tracer.spanBuilder(A2AMethods.GET_EXTENDED_AGENT_CARD_METHOD).setSpanKind(SpanKind.CLIENT);
spanBuilder.setAttribute(GENAI_OPERATION_NAME, A2AMethods.GET_EXTENDED_AGENT_CARD_METHOD);
Span span = spanBuilder.startSpan();
try (Scope scope = span.makeCurrent()) {
- AgentCard result = delegate.getExtendedAgentCard(clientContext);
+ AgentCard result = delegate.getExtendedAgentCard(params, clientContext);
if (result != null && extractResponse()) {
span.setAttribute(GENAI_RESPONSE, result.toString());
}
diff --git a/extras/opentelemetry/client/src/test/java/io/a2a/extras/opentelemetry/client/OpenTelemetryClientTransportTest.java b/extras/opentelemetry/client/src/test/java/io/a2a/extras/opentelemetry/client/OpenTelemetryClientTransportTest.java
index e930c18e1..d8a977424 100644
--- a/extras/opentelemetry/client/src/test/java/io/a2a/extras/opentelemetry/client/OpenTelemetryClientTransportTest.java
+++ b/extras/opentelemetry/client/src/test/java/io/a2a/extras/opentelemetry/client/OpenTelemetryClientTransportTest.java
@@ -12,6 +12,7 @@
import io.a2a.spec.AgentCard;
import io.a2a.spec.DeleteTaskPushNotificationConfigParams;
import io.a2a.spec.EventKind;
+import io.a2a.spec.GetExtendedAgentCardParams;
import io.a2a.spec.GetTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
import io.a2a.spec.ListTaskPushNotificationConfigResult;
@@ -323,9 +324,10 @@ void testSubscribeToTask() throws A2AClientException {
void testGetAgentCard_Success() throws A2AClientException {
AgentCard expectedResult = mock(AgentCard.class);
when(expectedResult.toString()).thenReturn("response-string");
- when(delegate.getExtendedAgentCard(any(ClientCallContext.class))).thenReturn(expectedResult);
+ when(delegate.getExtendedAgentCard(any(GetExtendedAgentCardParams.class), any(ClientCallContext.class))).thenReturn(expectedResult);
- AgentCard result = transport.getExtendedAgentCard(context);
+ GetExtendedAgentCardParams params = mock(GetExtendedAgentCardParams.class);
+ AgentCard result = transport.getExtendedAgentCard(params, context);
assertEquals(expectedResult, result);
verify(tracer).spanBuilder(A2AMethods.GET_EXTENDED_AGENT_CARD_METHOD);
@@ -337,9 +339,10 @@ void testGetAgentCard_Success() throws A2AClientException {
@Test
void testGetAgentCard_NullResponse() throws A2AClientException {
- when(delegate.getExtendedAgentCard(any(ClientCallContext.class))).thenReturn(null);
+ when(delegate.getExtendedAgentCard(any(GetExtendedAgentCardParams.class), any(ClientCallContext.class))).thenReturn(null);
- AgentCard result = transport.getExtendedAgentCard(context);
+ GetExtendedAgentCardParams params = mock(GetExtendedAgentCardParams.class);
+ AgentCard result = transport.getExtendedAgentCard(params, context);
assertNull(result);
verify(tracer).spanBuilder(A2AMethods.GET_EXTENDED_AGENT_CARD_METHOD);
diff --git a/spec-grpc/src/main/java/io/a2a/grpc/utils/ProtoUtils.java b/spec-grpc/src/main/java/io/a2a/grpc/utils/ProtoUtils.java
index d4b1ca55f..ebd859909 100644
--- a/spec-grpc/src/main/java/io/a2a/grpc/utils/ProtoUtils.java
+++ b/spec-grpc/src/main/java/io/a2a/grpc/utils/ProtoUtils.java
@@ -27,6 +27,7 @@
import io.a2a.spec.AgentCard;
import io.a2a.spec.DeleteTaskPushNotificationConfigParams;
import io.a2a.spec.EventKind;
+import io.a2a.spec.GetExtendedAgentCardParams;
import io.a2a.spec.GetTaskPushNotificationConfigParams;
import io.a2a.spec.InvalidParamsError;
import io.a2a.spec.ListTaskPushNotificationConfigParams;
@@ -55,8 +56,12 @@ public static io.a2a.grpc.AgentCard agentCard(AgentCard agentCard) {
return AgentCardMapper.INSTANCE.toProto(agentCard);
}
- public static io.a2a.grpc.GetExtendedAgentCardRequest extendedAgentCard() {
- return GetExtendedAgentCardRequest.newBuilder().build();
+ public static io.a2a.grpc.GetExtendedAgentCardRequest extendedAgentCard(GetExtendedAgentCardParams params) {
+ GetExtendedAgentCardRequest.Builder builder = GetExtendedAgentCardRequest.newBuilder();
+ if (params.tenant() != null) {
+ builder.setTenant(params.tenant());
+ }
+ return builder.build();
}
public static io.a2a.grpc.GetTaskRequest getTaskRequest(TaskQueryParams params) {
diff --git a/spec/src/main/java/io/a2a/spec/GetExtendedAgentCardParams.java b/spec/src/main/java/io/a2a/spec/GetExtendedAgentCardParams.java
new file mode 100644
index 000000000..c103c6a2a
--- /dev/null
+++ b/spec/src/main/java/io/a2a/spec/GetExtendedAgentCardParams.java
@@ -0,0 +1,12 @@
+package io.a2a.spec;
+
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Parameters to get the extended agent card.
+ *
+ * @param tenant optional tenant, provided as a path parameter.
+ * @see A2A Protocol Specification
+ */
+public record GetExtendedAgentCardParams(@Nullable String tenant) {
+}