@@ -44,13 +44,19 @@ def __init__(
4444 self .httpx_client = httpx_client
4545
4646 async def get_agent_card (
47- self , http_kwargs : dict [str , Any ] | None = None
47+ self ,
48+ relative_card_path : str | None = None ,
49+ http_kwargs : dict [str , Any ] | None = None ,
4850 ) -> AgentCard :
49- # Fetch the initial public agent card
50- public_card_url = f'{ self .base_url } /{ self .agent_card_path } '
51- """Fetches the agent card from the specified URL.
51+ """Fetches an agent card from a specified path relative to the base_url.
52+
53+ If relative_card_path is None, it defaults to the resolver's configured
54+ agent_card_path (for the public agent card).
5255
5356 Args:
57+ relative_card_path: Optional path to the agent card endpoint,
58+ relative to the base URL. If None, uses the default public
59+ agent card path.
5460 http_kwargs: Optional dictionary of keyword arguments to pass to the
5561 underlying httpx.get request.
5662
@@ -62,89 +68,45 @@ async def get_agent_card(
6268 A2AClientJSONError: If the response body cannot be decoded as JSON
6369 or validated against the AgentCard schema.
6470 """
71+ if relative_card_path is None :
72+ # Use the default public agent card path configured during initialization
73+ path_segment = self .agent_card_path
74+ else :
75+ path_segment = relative_card_path .lstrip ('/' )
76+
77+ target_url = f'{ self .base_url } /{ path_segment } '
78+
6579 try :
6680 response = await self .httpx_client .get (
67- public_card_url ,
81+ target_url ,
6882 ** (http_kwargs or {}),
6983 )
7084 response .raise_for_status ()
71- public_agent_card_data = response .json ()
85+ agent_card_data = response .json ()
7286 logger .info (
73- 'Successfully fetched public agent card data: %s' ,
74- public_agent_card_data ,
75- ) # Added for verbosity
76- # print(f"DEBUG: Fetched public agent card data:\n{json.dumps(public_agent_card_data, indent=2)}") # Added for direct output
77- agent_card = AgentCard .model_validate (public_agent_card_data )
87+ 'Successfully fetched agent card data from %s : %s' ,
88+ target_url ,
89+ agent_card_data ,
90+ )
91+ agent_card = AgentCard .model_validate (agent_card_data )
7892 except httpx .HTTPStatusError as e :
7993 raise A2AClientHTTPError (
8094 e .response .status_code ,
81- f'Failed to fetch public agent card from { public_card_url } : { e } ' ,
95+ f'Failed to fetch agent card from { target_url } : { e } ' ,
8296 ) from e
8397 except json .JSONDecodeError as e :
8498 raise A2AClientJSONError (
85- f'Failed to parse JSON for public agent card from { public_card_url } : { e } '
99+ f'Failed to parse JSON for agent card from { target_url } : { e } '
86100 ) from e
87101 except httpx .RequestError as e :
88102 raise A2AClientHTTPError (
89103 503 ,
90- f'Network communication error fetching public agent card from { public_card_url } : { e } ' ,
104+ f'Network communication error fetching agent card from { target_url } : { e } ' ,
105+ ) from e
106+ except ValidationError as e : # Pydantic validation error
107+ raise A2AClientJSONError (
108+ f'Failed to validate agent card structure from { target_url } : { e .json ()} '
91109 ) from e
92-
93- # Check for supportsAuthenticatedExtendedCard
94- if agent_card .supportsAuthenticatedExtendedCard :
95- # Construct URL for the extended card.
96- # The extended card URL is relative to the agent's base URL specified *in* the agent card.
97- if not agent_card .url :
98- logger .warning (
99- 'Agent card (from %s) indicates support for an extended card '
100- "but does not specify its own base 'url' field. "
101- 'Cannot fetch extended card. Proceeding with public card.' ,
102- public_card_url ,
103- )
104- return agent_card
105-
106- extended_card_base_url = agent_card .url .rstrip ('/' )
107- full_extended_card_url = (
108- f'{ extended_card_base_url } /{ self .extended_agent_card_path } '
109- )
110-
111- logger .info (
112- 'Attempting to fetch extended agent card from %s' ,
113- full_extended_card_url ,
114- )
115- try :
116- # Make another GET request for the extended card
117- # Note: Authentication headers will be added here when auth is implemented.
118- extended_response = await self .httpx_client .get (
119- full_extended_card_url ,
120- ** (http_kwargs or {}), # Passing original http_kwargs
121- )
122- extended_response .raise_for_status ()
123- extended_agent_card_data = extended_response .json ()
124- logger .info (
125- 'Successfully fetched extended agent card data: %s' ,
126- extended_agent_card_data ,
127- ) # Added for verbosity
128-
129- # This new card data replaces the old one entirely
130- agent_card = AgentCard .model_validate (extended_agent_card_data )
131- logger .info (
132- 'Successfully fetched and using extended agent card from %s' ,
133- full_extended_card_url ,
134- )
135- except (
136- httpx .HTTPStatusError ,
137- httpx .RequestError ,
138- json .JSONDecodeError ,
139- ValidationError ,
140- ) as e :
141- logger .warning (
142- 'Failed to fetch or parse extended agent card from %s. Error: %s. '
143- 'Proceeding with the initially fetched public agent card.' ,
144- full_extended_card_url ,
145- e ,
146- )
147- # Fallback to the already parsed public_agent_card (which is 'agent_card' at this point)
148110
149111 return agent_card
150112
@@ -187,14 +149,17 @@ async def get_client_from_agent_card_url(
187149 agent_card_path : str = '/.well-known/agent.json' ,
188150 http_kwargs : dict [str , Any ] | None = None ,
189151 ) -> 'A2AClient' :
190- """Fetches the AgentCard and initializes an A2A client.
152+ """Fetches the public AgentCard and initializes an A2A client.
153+
154+ This method will always fetch the public agent card. If an authenticated
155+ or extended agent card is required, the A2ACardResolver should be used
156+ directly to fetch the specific card, and then the A2AClient should be
157+ instantiated with it.
191158
192159 Args:
193160 httpx_client: An async HTTP client instance (e.g., httpx.AsyncClient).
194161 base_url: The base URL of the agent's host.
195162 agent_card_path: The path to the agent card endpoint, relative to the base URL.
196- http_kwargs: Optional dictionary of keyword arguments to pass to the
197- underlying httpx.get request when fetching the agent card.
198163
199164 Returns:
200165 An initialized `A2AClient` instance.
@@ -205,7 +170,7 @@ async def get_client_from_agent_card_url(
205170 """
206171 agent_card : AgentCard = await A2ACardResolver (
207172 httpx_client , base_url = base_url , agent_card_path = agent_card_path
208- ).get_agent_card (http_kwargs = http_kwargs )
173+ ).get_agent_card (http_kwargs = http_kwargs ) # Fetches public card by default
209174 return A2AClient (httpx_client = httpx_client , agent_card = agent_card )
210175
211176 async def send_message (
0 commit comments