11using Microsoft . Extensions . Logging ;
22using Microsoft . Extensions . Logging . Abstractions ;
3+ using System . Diagnostics ;
4+ using System . Net ;
35using System . Text . Json ;
46
57namespace A2A ;
@@ -9,30 +11,34 @@ namespace A2A;
911/// </summary>
1012public sealed class A2ACardResolver
1113{
14+ private readonly HttpClient _httpClient ;
15+ private readonly Uri _agentCardPath ;
16+ private readonly ILogger _logger ;
17+
1218 /// <summary>
1319 /// Creates a new instance of the A2ACardResolver
1420 /// </summary>
15- /// <param name="httpClient">Optional HTTP client (if not provided, a new one will be created )</param>
16- /// <param name="agentCardPath">Path to the agent card (defaults to /.well-known/agent.json)</param>
21+ /// <param name="httpClient">Optional HTTP client (if not provided, a shared one will be used )</param>
22+ /// <param name="agentCardPath">Path to the agent card (defaults to " /.well-known/agent.json" )</param>
1723 /// <param name="logger">Optional logger</param>
1824 public A2ACardResolver (
19- HttpClient httpClient ,
25+ HttpClient ? httpClient ,
2026 string agentCardPath = "/.well-known/agent.json" ,
2127 ILogger ? logger = null )
2228 {
23- _agentCardPath = agentCardPath . TrimStart ( '/' ) ;
24- _httpClient = httpClient ;
25- _httpClient . Timeout = TimeSpan . FromSeconds ( 30 ) ; // Set a reasonable timeout
29+ if ( agentCardPath is null )
30+ {
31+ throw new ArgumentNullException ( nameof ( agentCardPath ) , "Agent card path cannot be null." ) ;
32+ }
33+
34+ _httpClient = httpClient ?? A2AClient . s_sharedClient ;
35+ _agentCardPath = new Uri ( agentCardPath . TrimStart ( '/' ) , UriKind . RelativeOrAbsolute ) ;
2636 _logger = logger ?? NullLogger . Instance ;
27- }
2837
29- /// <summary>
30- /// Gets the agent card synchronously
31- /// </summary>
32- /// <returns>The agent card</returns>
33- public AgentCard GetAgentCard ( )
34- {
35- return GetAgentCardAsync ( ) . GetAwaiter ( ) . GetResult ( ) ;
38+ if ( _httpClient . BaseAddress is null && ! _agentCardPath . IsAbsoluteUri )
39+ {
40+ throw new ArgumentException ( $ "HttpClient.BaseAddress must be set when using a relative { nameof ( agentCardPath ) } .", nameof ( httpClient ) ) ;
41+ }
3642 }
3743
3844 /// <summary>
@@ -42,44 +48,44 @@ public AgentCard GetAgentCard()
4248 /// <returns>The agent card</returns>
4349 public async Task < AgentCard > GetAgentCardAsync ( CancellationToken cancellationToken = default )
4450 {
45- string url = $ "{ _httpClient . BaseAddress } /{ _agentCardPath } ";
46- _logger ? . LogInformation ( "Fetching agent card from {Url}" , url ) ;
51+ if ( _logger . IsEnabled ( LogLevel . Information ) )
52+ {
53+ Debug . Assert ( _agentCardPath . IsAbsoluteUri || _httpClient . BaseAddress is not null ) ;
54+ _logger . LogInformation ( "Fetching agent card from '{Url}'" , _agentCardPath . IsAbsoluteUri ?
55+ _agentCardPath :
56+ new Uri ( _httpClient . BaseAddress ! , _agentCardPath . ToString ( ) ) ) ;
57+ }
4758
4859 try
4960 {
50- var response = await _httpClient . GetAsync ( _agentCardPath , cancellationToken ) ;
61+ using var response = await _httpClient . GetAsync ( _agentCardPath , HttpCompletionOption . ResponseHeadersRead , cancellationToken ) . ConfigureAwait ( false ) ;
5162
5263 response . EnsureSuccessStatusCode ( ) ;
5364
54- var content = await response . Content . ReadAsStreamAsync (
55- #if NET8_0_OR_GREATER
65+ using var responseStream = await response . Content . ReadAsStreamAsync (
66+ #if NET
5667 cancellationToken
5768#endif
58- ) ;
69+ ) . ConfigureAwait ( false ) ;
5970
60- return JsonSerializer . Deserialize ( content , A2AJsonUtilities . JsonContext . Default . AgentCard ) ??
71+ return JsonSerializer . Deserialize ( responseStream , A2AJsonUtilities . JsonContext . Default . AgentCard ) ??
6172 throw new A2AClientJsonException ( "Failed to parse agent card JSON." ) ;
6273 }
6374 catch ( JsonException ex )
6475 {
65- _logger ? . LogError ( ex , "Failed to parse agent card JSON" ) ;
76+ _logger . LogError ( ex , "Failed to parse agent card JSON" ) ;
6677 throw new A2AClientJsonException ( $ "Failed to parse JSON: { ex . Message } ") ;
6778 }
6879 catch ( HttpRequestException ex )
6980 {
70- #if NET8_0_OR_GREATER
71- int statusCode = ( int ) ( ex . StatusCode ?? System . Net . HttpStatusCode . InternalServerError ) ;
72- #else
73- int statusCode = ( int ) System . Net . HttpStatusCode . InternalServerError ;
81+ HttpStatusCode statusCode =
82+ #if NET
83+ ex . StatusCode ??
7484#endif
75- _logger ? . LogError ( ex , "HTTP request failed with status code {StatusCode}" , statusCode ) ;
85+ HttpStatusCode . InternalServerError ;
86+
87+ _logger . LogError ( ex , "HTTP request failed with status code {StatusCode}" , statusCode ) ;
7688 throw new A2AClientHTTPException ( statusCode , ex . Message ) ;
7789 }
7890 }
79-
80- #region private
81- private readonly HttpClient _httpClient ;
82- private readonly string _agentCardPath ;
83- private readonly ILogger _logger ;
84- #endregion
8591}
0 commit comments