@@ -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,8 +212,8 @@ public ListTasksResult listTasks(ListTasksParams request, @Nullable ClientCallCo
212212
213213 try {
214214 // Build query string
215- StringBuilder urlBuilder = new StringBuilder (agentUrl );
216- urlBuilder .append ("/v1/ tasks" );
215+ StringBuilder urlBuilder = new StringBuilder (buildBaseUrl ( request . tenant ()) );
216+ urlBuilder .append ("/tasks" );
217217 String queryParams = buildListTasksQueryString (request );
218218 if (!queryParams .isEmpty ()) {
219219 urlBuilder .append ("?" ).append (queryParams );
@@ -246,6 +246,25 @@ public ListTasksResult listTasks(ListTasksParams request, @Nullable ClientCallCo
246246 }
247247 }
248248
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 (0 , tenantPath .length () -1 );
265+ }
266+ return tenantPath ;
267+ }
249268 private String buildListTasksQueryString (ListTasksParams request ) {
250269 java .util .List <String > queryParts = new java .util .ArrayList <>();
251270 if (request .contextId () != null ) {
@@ -281,7 +300,7 @@ public TaskPushNotificationConfig setTaskPushNotificationConfiguration(TaskPushN
281300 }
282301 PayloadAndHeaders payloadAndHeaders = applyInterceptors (SetTaskPushNotificationConfigRequest .METHOD , builder , agentCard , context );
283302 try {
284- 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 );
285304 io .a2a .grpc .TaskPushNotificationConfig .Builder responseBuilder = io .a2a .grpc .TaskPushNotificationConfig .newBuilder ();
286305 JsonFormat .parser ().merge (httpResponseBody , responseBuilder );
287306 return ProtoUtils .FromProto .taskPushNotificationConfig (responseBuilder );
@@ -297,11 +316,23 @@ public TaskPushNotificationConfig getTaskPushNotificationConfiguration(GetTaskPu
297316 checkNotNullParam ("request" , request );
298317 io .a2a .grpc .GetTaskPushNotificationConfigRequest .Builder builder
299318 = io .a2a .grpc .GetTaskPushNotificationConfigRequest .newBuilder ();
300- 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+ }
301326 PayloadAndHeaders payloadAndHeaders = applyInterceptors (GetTaskPushNotificationConfigRequest .METHOD , builder ,
302327 agentCard , context );
303328 try {
304- 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+ }
305336 A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url );
306337 if (payloadAndHeaders .getHeaders () != null ) {
307338 for (Map .Entry <String , String > entry : payloadAndHeaders .getHeaders ().entrySet ()) {
@@ -332,7 +363,7 @@ public List<TaskPushNotificationConfig> listTaskPushNotificationConfigurations(L
332363 PayloadAndHeaders payloadAndHeaders = applyInterceptors (ListTaskPushNotificationConfigRequest .METHOD , builder ,
333364 agentCard , context );
334365 try {
335- String url = agentUrl + String .format ("/v1 /tasks/%1s/pushNotificationConfigs" , request .id ());
366+ String url = buildBaseUrl ( request . tenant ()) + String .format ("/tasks/%1s/pushNotificationConfigs" , request .id ());
336367 A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url );
337368 if (payloadAndHeaders .getHeaders () != null ) {
338369 for (Map .Entry <String , String > entry : payloadAndHeaders .getHeaders ().entrySet ()) {
@@ -361,7 +392,7 @@ public void deleteTaskPushNotificationConfigurations(DeleteTaskPushNotificationC
361392 PayloadAndHeaders payloadAndHeaders = applyInterceptors (DeleteTaskPushNotificationConfigRequest .METHOD , builder ,
362393 agentCard , context );
363394 try {
364- 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 ());
365396 A2AHttpClient .DeleteBuilder deleteBuilder = httpClient .createDelete ().url (url );
366397 if (payloadAndHeaders .getHeaders () != null ) {
367398 for (Map .Entry <String , String > entry : payloadAndHeaders .getHeaders ().entrySet ()) {
@@ -390,7 +421,7 @@ public void resubscribe(TaskIdParams request, Consumer<StreamingEventKind> event
390421 AtomicReference <CompletableFuture <Void >> ref = new AtomicReference <>();
391422 RestSSEEventListener sseEventListener = new RestSSEEventListener (eventConsumer , errorConsumer );
392423 try {
393- String url = agentUrl + String .format ("/v1 /tasks/%1s:subscribe" , request .id ());
424+ String url = buildBaseUrl ( request . tenant ()) + String .format ("/tasks/%1s:subscribe" , request .id ());
394425 A2AHttpClient .PostBuilder postBuilder = createPostBuilder (url , payloadAndHeaders );
395426 ref .set (postBuilder .postAsyncSSE (
396427 msg -> sseEventListener .onMessage (msg , ref .get ()),
@@ -421,7 +452,7 @@ public AgentCard getAgentCard(@Nullable ClientCallContext context) throws A2ACli
421452 }
422453 PayloadAndHeaders payloadAndHeaders = applyInterceptors (GetTaskRequest .METHOD , null ,
423454 agentCard , context );
424- String url = agentUrl + String .format ("/v1/card " );
455+ String url = buildBaseUrl ( "" ) + String .format ("/extendedAgentCard " );
425456 A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url );
426457 if (payloadAndHeaders .getHeaders () != null ) {
427458 for (Map .Entry <String , String > entry : payloadAndHeaders .getHeaders ().entrySet ()) {
0 commit comments