@@ -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 ()),
@@ -135,13 +135,13 @@ public Task getTask(TaskQueryParams taskQueryParams, @Nullable ClientCallContext
135135 PayloadAndHeaders payloadAndHeaders = applyInterceptors (GetTaskRequest .METHOD , builder ,
136136 agentCard , context );
137137 try {
138- String url ;
138+ StringBuilder url = new StringBuilder ( buildBaseUrl ( taskQueryParams . tenant ())) ;
139139 if (taskQueryParams .historyLength () != null && taskQueryParams .historyLength () > 0 ) {
140- url = agentUrl + String .format ("/v1/ tasks/%1s?historyLength=%2d" , taskQueryParams .id (), taskQueryParams .historyLength ());
140+ url . append ( String .format ("/tasks/%1s?historyLength=%2d" , taskQueryParams .id (), taskQueryParams .historyLength () ));
141141 } else {
142- url = agentUrl + String .format ("/v1/ tasks/%1s" , taskQueryParams .id ());
142+ url . append ( String .format ("/tasks/%1s" , taskQueryParams .id () ));
143143 }
144- A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url );
144+ A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url . toString () );
145145 if (payloadAndHeaders .getHeaders () != null ) {
146146 for (Map .Entry <String , String > entry : payloadAndHeaders .getHeaders ().entrySet ()) {
147147 getBuilder .addHeader (entry .getKey (), entry .getValue ());
@@ -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,12 +316,20 @@ 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+ StringBuilder url = new StringBuilder (buildBaseUrl (request .tenant ()));
320+ String configId = request .pushNotificationConfigId ();
321+ if (configId != null && !configId .isEmpty ()) {
322+ builder .setName (String .format ("/tasks/%1s/pushNotificationConfigs/%2s" , request .id (), configId ));
323+ url .append (builder .getName ());
324+ } else {
325+ // Use trailing slash to distinguish GET from LIST
326+ builder .setName (String .format ("/tasks/%1s/pushNotificationConfigs/" , request .id ()));
327+ url .append (builder .getName ());
328+ }
301329 PayloadAndHeaders payloadAndHeaders = applyInterceptors (GetTaskPushNotificationConfigRequest .METHOD , builder ,
302330 agentCard , context );
303331 try {
304- String url = agentUrl + String .format ("/v1/tasks/%1s/pushNotificationConfigs/%2s" , request .id (), request .pushNotificationConfigId ());
305- A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url );
332+ A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url .toString ());
306333 if (payloadAndHeaders .getHeaders () != null ) {
307334 for (Map .Entry <String , String > entry : payloadAndHeaders .getHeaders ().entrySet ()) {
308335 getBuilder .addHeader (entry .getKey (), entry .getValue ());
@@ -332,7 +359,7 @@ public List<TaskPushNotificationConfig> listTaskPushNotificationConfigurations(L
332359 PayloadAndHeaders payloadAndHeaders = applyInterceptors (ListTaskPushNotificationConfigRequest .METHOD , builder ,
333360 agentCard , context );
334361 try {
335- String url = agentUrl + String .format ("/v1 /tasks/%1s/pushNotificationConfigs" , request .id ());
362+ String url = buildBaseUrl ( request . tenant ()) + String .format ("/tasks/%1s/pushNotificationConfigs" , request .id ());
336363 A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url );
337364 if (payloadAndHeaders .getHeaders () != null ) {
338365 for (Map .Entry <String , String > entry : payloadAndHeaders .getHeaders ().entrySet ()) {
@@ -361,7 +388,7 @@ public void deleteTaskPushNotificationConfigurations(DeleteTaskPushNotificationC
361388 PayloadAndHeaders payloadAndHeaders = applyInterceptors (DeleteTaskPushNotificationConfigRequest .METHOD , builder ,
362389 agentCard , context );
363390 try {
364- String url = agentUrl + String .format ("/v1 /tasks/%1s/pushNotificationConfigs/%2s" , request .id (), request .pushNotificationConfigId ());
391+ String url = buildBaseUrl ( request . tenant ()) + String .format ("/tasks/%1s/pushNotificationConfigs/%2s" , request .id (), request .pushNotificationConfigId ());
365392 A2AHttpClient .DeleteBuilder deleteBuilder = httpClient .createDelete ().url (url );
366393 if (payloadAndHeaders .getHeaders () != null ) {
367394 for (Map .Entry <String , String > entry : payloadAndHeaders .getHeaders ().entrySet ()) {
@@ -390,7 +417,7 @@ public void resubscribe(TaskIdParams request, Consumer<StreamingEventKind> event
390417 AtomicReference <CompletableFuture <Void >> ref = new AtomicReference <>();
391418 RestSSEEventListener sseEventListener = new RestSSEEventListener (eventConsumer , errorConsumer );
392419 try {
393- String url = agentUrl + String .format ("/v1 /tasks/%1s:subscribe" , request .id ());
420+ String url = buildBaseUrl ( request . tenant ()) + String .format ("/tasks/%1s:subscribe" , request .id ());
394421 A2AHttpClient .PostBuilder postBuilder = createPostBuilder (url , payloadAndHeaders );
395422 ref .set (postBuilder .postAsyncSSE (
396423 msg -> sseEventListener .onMessage (msg , ref .get ()),
@@ -421,7 +448,7 @@ public AgentCard getAgentCard(@Nullable ClientCallContext context) throws A2ACli
421448 }
422449 PayloadAndHeaders payloadAndHeaders = applyInterceptors (GetTaskRequest .METHOD , null ,
423450 agentCard , context );
424- String url = agentUrl + String .format ("/v1/card " );
451+ String url = buildBaseUrl ( "" ) + String .format ("/extendedAgentCard " );
425452 A2AHttpClient .GetBuilder getBuilder = httpClient .createGet ().url (url );
426453 if (payloadAndHeaders .getHeaders () != null ) {
427454 for (Map .Entry <String , String > entry : payloadAndHeaders .getHeaders ().entrySet ()) {
0 commit comments