@@ -83,7 +83,7 @@ public EventKind sendMessage(MessageSendParams messageSendParams, @Nullable Clie
8383 io .a2a .grpc .SendMessageRequest .Builder builder = io .a2a .grpc .SendMessageRequest .newBuilder (ProtoUtils .ToProto .sendMessageRequest (messageSendParams ));
8484 PayloadAndHeaders payloadAndHeaders = applyInterceptors (SendMessageRequest .METHOD , builder , agentCard , context );
8585 try {
86- String httpResponseBody = sendPostRequest (agentUrl + "/v1 /message:send" , payloadAndHeaders );
86+ String httpResponseBody = sendPostRequest (buildBaseUrl ( messageSendParams . tenant ()) + "/message:send" , payloadAndHeaders );
8787 io .a2a .grpc .SendMessageResponse .Builder responseBuilder = io .a2a .grpc .SendMessageResponse .newBuilder ();
8888 JsonFormat .parser ().merge (httpResponseBody , responseBuilder );
8989 if (responseBuilder .hasMsg ()) {
@@ -111,7 +111,7 @@ public void sendMessageStreaming(MessageSendParams messageSendParams, Consumer<S
111111 AtomicReference <CompletableFuture <Void >> ref = new AtomicReference <>();
112112 RestSSEEventListener sseEventListener = new RestSSEEventListener (eventConsumer , errorConsumer );
113113 try {
114- A2AHttpClient .PostBuilder postBuilder = createPostBuilder (agentUrl + "/v1 /message:stream" , payloadAndHeaders );
114+ A2AHttpClient .PostBuilder postBuilder = createPostBuilder (buildBaseUrl ( messageSendParams . tenant ()) + "/message:stream" , payloadAndHeaders );
115115 ref .set (postBuilder .postAsyncSSE (
116116 msg -> sseEventListener .onMessage (msg , ref .get ()),
117117 throwable -> sseEventListener .onError (throwable , ref .get ()),
@@ -137,9 +137,9 @@ public Task getTask(TaskQueryParams taskQueryParams, @Nullable ClientCallContext
137137 try {
138138 String url ;
139139 if (taskQueryParams .historyLength () != null && taskQueryParams .historyLength () > 0 ) {
140- url = agentUrl + String .format ("/v1 /tasks/%1s?historyLength=%2d" , taskQueryParams .id (), taskQueryParams .historyLength ());
140+ url = buildBaseUrl ( taskQueryParams . tenant ()) + String .format ("/tasks/%1s?historyLength=%2d" , taskQueryParams .id (), taskQueryParams .historyLength ());
141141 } else {
142- url = agentUrl + String .format ("/v1 /tasks/%1s" , taskQueryParams .id ());
142+ url = buildBaseUrl ( taskQueryParams . tenant ()) + String .format ("/tasks/%1s" , taskQueryParams .id ());
143143 }
144144 A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url );
145145 if (payloadAndHeaders .getHeaders () != null ) {
@@ -170,7 +170,7 @@ public Task cancelTask(TaskIdParams taskIdParams, @Nullable ClientCallContext co
170170 PayloadAndHeaders payloadAndHeaders = applyInterceptors (CancelTaskRequest .METHOD , builder ,
171171 agentCard , context );
172172 try {
173- String httpResponseBody = sendPostRequest (agentUrl + String .format ("/v1 /tasks/%1s:cancel" , taskIdParams .id ()), payloadAndHeaders );
173+ String httpResponseBody = sendPostRequest (buildBaseUrl ( taskIdParams . tenant ()) + String .format ("/tasks/%1s:cancel" , taskIdParams .id ()), payloadAndHeaders );
174174 io .a2a .grpc .Task .Builder responseBuilder = io .a2a .grpc .Task .newBuilder ();
175175 JsonFormat .parser ().merge (httpResponseBody , responseBuilder );
176176 return ProtoUtils .FromProto .task (responseBuilder );
@@ -212,11 +212,8 @@ public ListTasksResult listTasks(ListTasksParams request, @Nullable ClientCallCo
212212
213213 try {
214214 // Build query string
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" );
215+ StringBuilder urlBuilder = new StringBuilder (buildBaseUrl (request .tenant ()));
216+ urlBuilder .append ("/tasks" );
220217 String queryParams = buildListTasksQueryString (request );
221218 if (!queryParams .isEmpty ()) {
222219 urlBuilder .append ("?" ).append (queryParams );
@@ -249,6 +246,25 @@ public ListTasksResult listTasks(ListTasksParams request, @Nullable ClientCallCo
249246 }
250247 }
251248
249+ private String buildBaseUrl (@ Nullable String tenant ) {
250+ StringBuilder urlBuilder = new StringBuilder (agentUrl );
251+ urlBuilder .append (extractTenant (tenant ));
252+ return urlBuilder .toString ();
253+ }
254+
255+ private String extractTenant (@ Nullable String tenant ) {
256+ String tenantPath = tenant ;
257+ if (tenantPath == null || tenantPath .isBlank ()) {
258+ return "" ;
259+ }
260+ if (! tenantPath .startsWith ("/" )){
261+ tenantPath = '/' + tenantPath ;
262+ }
263+ if (!tenantPath .endsWith ("/" )){
264+ tenantPath = tenantPath .substring (tenantPath .lastIndexOf ('/' ));
265+ }
266+ return tenantPath ;
267+ }
252268 private String buildListTasksQueryString (ListTasksParams request ) {
253269 java .util .List <String > queryParts = new java .util .ArrayList <>();
254270 if (request .contextId () != null ) {
@@ -284,7 +300,7 @@ public TaskPushNotificationConfig setTaskPushNotificationConfiguration(TaskPushN
284300 }
285301 PayloadAndHeaders payloadAndHeaders = applyInterceptors (SetTaskPushNotificationConfigRequest .METHOD , builder , agentCard , context );
286302 try {
287- String httpResponseBody = sendPostRequest (agentUrl + String .format ("/v1 /tasks/%1s/pushNotificationConfigs" , request .taskId ()), payloadAndHeaders );
303+ String httpResponseBody = sendPostRequest (buildBaseUrl ( request . tenant ()) + String .format ("/tasks/%1s/pushNotificationConfigs" , request .taskId ()), payloadAndHeaders );
288304 io .a2a .grpc .TaskPushNotificationConfig .Builder responseBuilder = io .a2a .grpc .TaskPushNotificationConfig .newBuilder ();
289305 JsonFormat .parser ().merge (httpResponseBody , responseBuilder );
290306 return ProtoUtils .FromProto .taskPushNotificationConfig (responseBuilder );
@@ -300,11 +316,23 @@ public TaskPushNotificationConfig getTaskPushNotificationConfiguration(GetTaskPu
300316 checkNotNullParam ("request" , request );
301317 io .a2a .grpc .GetTaskPushNotificationConfigRequest .Builder builder
302318 = io .a2a .grpc .GetTaskPushNotificationConfigRequest .newBuilder ();
303- builder .setName (String .format ("/tasks/%1s/pushNotificationConfigs/%2s" , request .id (), request .pushNotificationConfigId ()));
319+ String configId = request .pushNotificationConfigId ();
320+ if (configId != null && !configId .isEmpty ()) {
321+ builder .setName (String .format ("/tasks/%1s/pushNotificationConfigs/%2s" , request .id (), configId ));
322+ } else {
323+ // Use trailing slash to distinguish GET from LIST
324+ builder .setName (String .format ("/tasks/%1s/pushNotificationConfigs/" , request .id ()));
325+ }
304326 PayloadAndHeaders payloadAndHeaders = applyInterceptors (GetTaskPushNotificationConfigRequest .METHOD , builder ,
305327 agentCard , context );
306328 try {
307- String url = agentUrl + String .format ("/v1/tasks/%1s/pushNotificationConfigs/%2s" , request .id (), request .pushNotificationConfigId ());
329+ String url ;
330+ if (configId != null && !configId .isEmpty ()) {
331+ url = buildBaseUrl (request .tenant ()) + String .format ("/tasks/%1s/pushNotificationConfigs/%2s" , request .id (), configId );
332+ } else {
333+ // Trailing slash distinguishes GET from LIST
334+ url = buildBaseUrl (request .tenant ()) + String .format ("/tasks/%1s/pushNotificationConfigs/" , request .id ());
335+ }
308336 A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url );
309337 if (payloadAndHeaders .getHeaders () != null ) {
310338 for (Map .Entry <String , String > entry : payloadAndHeaders .getHeaders ().entrySet ()) {
@@ -335,7 +363,7 @@ public List<TaskPushNotificationConfig> listTaskPushNotificationConfigurations(L
335363 PayloadAndHeaders payloadAndHeaders = applyInterceptors (ListTaskPushNotificationConfigRequest .METHOD , builder ,
336364 agentCard , context );
337365 try {
338- String url = agentUrl + String .format ("/v1 /tasks/%1s/pushNotificationConfigs" , request .id ());
366+ String url = buildBaseUrl ( request . tenant ()) + String .format ("/tasks/%1s/pushNotificationConfigs" , request .id ());
339367 A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url );
340368 if (payloadAndHeaders .getHeaders () != null ) {
341369 for (Map .Entry <String , String > entry : payloadAndHeaders .getHeaders ().entrySet ()) {
@@ -364,7 +392,7 @@ public void deleteTaskPushNotificationConfigurations(DeleteTaskPushNotificationC
364392 PayloadAndHeaders payloadAndHeaders = applyInterceptors (DeleteTaskPushNotificationConfigRequest .METHOD , builder ,
365393 agentCard , context );
366394 try {
367- String url = agentUrl + String .format ("/v1 /tasks/%1s/pushNotificationConfigs/%2s" , request .id (), request .pushNotificationConfigId ());
395+ String url = buildBaseUrl ( request . tenant ()) + String .format ("/tasks/%1s/pushNotificationConfigs/%2s" , request .id (), request .pushNotificationConfigId ());
368396 A2AHttpClient .DeleteBuilder deleteBuilder = httpClient .createDelete ().url (url );
369397 if (payloadAndHeaders .getHeaders () != null ) {
370398 for (Map .Entry <String , String > entry : payloadAndHeaders .getHeaders ().entrySet ()) {
@@ -393,7 +421,7 @@ public void resubscribe(TaskIdParams request, Consumer<StreamingEventKind> event
393421 AtomicReference <CompletableFuture <Void >> ref = new AtomicReference <>();
394422 RestSSEEventListener sseEventListener = new RestSSEEventListener (eventConsumer , errorConsumer );
395423 try {
396- String url = agentUrl + String .format ("/v1 /tasks/%1s:subscribe" , request .id ());
424+ String url = buildBaseUrl ( request . tenant ()) + String .format ("/tasks/%1s:subscribe" , request .id ());
397425 A2AHttpClient .PostBuilder postBuilder = createPostBuilder (url , payloadAndHeaders );
398426 ref .set (postBuilder .postAsyncSSE (
399427 msg -> sseEventListener .onMessage (msg , ref .get ()),
@@ -424,7 +452,7 @@ public AgentCard getAgentCard(@Nullable ClientCallContext context) throws A2ACli
424452 }
425453 PayloadAndHeaders payloadAndHeaders = applyInterceptors (GetTaskRequest .METHOD , null ,
426454 agentCard , context );
427- String url = agentUrl + String .format ("/v1/card " );
455+ String url = buildBaseUrl ( "" ) + String .format ("/extendedAgentCard " );
428456 A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url );
429457 if (payloadAndHeaders .getHeaders () != null ) {
430458 for (Map .Entry <String , String > entry : payloadAndHeaders .getHeaders ().entrySet ()) {
0 commit comments