3434from uipath ._utils ._ssl_context import get_httpx_client_kwargs
3535from uipath .agent .models .agent import AgentA2aResourceConfig
3636
37+ from uipath_langchain ._utils import get_execution_folder_path
3738from uipath_langchain .agent .react .types import AgentGraphState
3839from uipath_langchain .agent .tools .base_uipath_structured_tool import (
3940 BaseUiPathStructuredTool ,
@@ -65,8 +66,9 @@ class A2aClient:
6566 pool when done.
6667 """
6768
68- def __init__ (self , agent_card : AgentCard ) -> None :
69+ def __init__ (self , agent_card : AgentCard , slug : str ) -> None :
6970 self ._agent_card = agent_card
71+ self ._slug = slug
7072 self ._lock = asyncio .Lock ()
7173 self ._client : Client | None = None
7274 self ._http_client : httpx .AsyncClient | None = None
@@ -80,6 +82,16 @@ async def get(self) -> Client:
8082 from uipath .platform import UiPath
8183
8284 sdk = UiPath ()
85+ folder_path = get_execution_folder_path ()
86+ agent = await sdk .remote_a2a .retrieve_async (
87+ slug = self ._slug , folder_path = folder_path
88+ )
89+ if not agent .a2a_url :
90+ raise ValueError (
91+ f"Remote A2A agent '{ self ._slug } ' has no a2a_url configured"
92+ )
93+ self ._agent_card .url = agent .a2a_url
94+
8395 client_kwargs = get_httpx_client_kwargs (
8496 headers = {"Authorization" : f"Bearer { sdk ._config .secret } " },
8597 )
@@ -152,19 +164,16 @@ def _build_description(card: AgentCard) -> str:
152164 skill_desc += f": { skill .description } "
153165 if skill_desc :
154166 parts .append (f"Skill: { skill_desc } " )
155- return " | " .join (parts ) if parts else f"Remote A2A agent at { card .url } "
156-
157-
158- def _resolve_a2a_url (config : AgentA2aResourceConfig ) -> str :
159- """Resolve the A2A endpoint URL, using the UiPath-hosted proxy URL."""
160- if config .a2a_url :
161- return config .a2a_url
162- raise ValueError (f"A2A resource '{ config .name } ' has no URL" )
167+ if parts :
168+ return " | " .join (parts )
169+ # The card URL is resolved lazily at runtime, so it is empty or stale here;
170+ # fall back to the agent name rather than exposing an internal/blank URL.
171+ return f"Remote A2A agent: { card .name } " if card .name else "Remote A2A agent"
163172
164173
165174async def _send_a2a_message (
166175 client : Client ,
167- a2a_url : str ,
176+ agent_label : str ,
168177 * ,
169178 message : str ,
170179 task_id : str | None ,
@@ -177,10 +186,10 @@ async def _send_a2a_message(
177186 """
178187 if task_id or context_id :
179188 logger .info (
180- "A2A continue task=%s context=%s to %s" , task_id , context_id , a2a_url
189+ "A2A continue task=%s context=%s to %s" , task_id , context_id , agent_label
181190 )
182191 else :
183- logger .info ("A2A new message to %s" , a2a_url )
192+ logger .info ("A2A new message to %s" , agent_label )
184193
185194 a2a_message = Message (
186195 role = Role .user ,
@@ -218,7 +227,7 @@ async def _send_a2a_message(
218227 return (text or "No response received." , state , new_task_id , new_context_id )
219228
220229 except Exception as e :
221- logger .exception ("A2A request to %s failed" , a2a_url )
230+ logger .exception ("A2A request to %s failed" , agent_label )
222231 return (f"Error: { e } " , "error" , task_id , context_id )
223232
224233
@@ -234,7 +243,7 @@ def _create_a2a_tool(
234243 raw_name = agent_card .name or config .name
235244 tool_name = sanitize_tool_name (raw_name )
236245 tool_description = _build_description (agent_card )
237- a2a_url = _resolve_a2a_url ( config )
246+ agent_label = config . slug
238247
239248 metadata = {
240249 "tool_type" : "a2a" ,
@@ -245,7 +254,7 @@ def _create_a2a_tool(
245254 async def _send (* , message : str ) -> str :
246255 client = await a2a_client .get ()
247256 text , state , _ , _ = await _send_a2a_message (
248- client , a2a_url , message = message , task_id = None , context_id = None
257+ client , agent_label , message = message , task_id = None , context_id = None
249258 )
250259 return _format_response (text , state )
251260
@@ -261,7 +270,7 @@ async def _a2a_wrapper(
261270 client = await a2a_client .get ()
262271 text , task_state , new_task_id , new_context_id = await _send_a2a_message (
263272 client ,
264- a2a_url ,
273+ agent_label ,
265274 message = call ["args" ]["message" ],
266275 task_id = task_id ,
267276 context_id = context_id ,
@@ -341,10 +350,7 @@ def create_a2a_tools_and_clients(
341350 default_output_modes = ["text/plain" ],
342351 )
343352
344- if resource .a2a_url :
345- agent_card .url = resource .a2a_url
346-
347- a2a_client = A2aClient (agent_card )
353+ a2a_client = A2aClient (agent_card , resource .slug )
348354 tool = _create_a2a_tool (resource , a2a_client , agent_card )
349355 tools .append (tool )
350356 clients .append (a2a_client )
0 commit comments