@dexwox-labs/a2a-client
Version:
TypeScript client implementation for Google's Agent-to-Agent (A2A) protocol - includes HTTP/WebSocket communication, circuit breakers and error handling
138 lines • 4.83 kB
JavaScript
;
/**
* @module AgentCardResolver
* @description Provides functionality to resolve and cache agent cards from agent servers
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.AgentCardResolver = void 0;
const circuit_breaker_1 = require("./utils/circuit-breaker");
/**
* Resolves and caches agent cards from agent servers
*
* This class handles fetching agent cards from agent servers with built-in
* caching and timeout handling. It follows the A2A protocol for agent discovery.
*
* @example
* ```typescript
* const resolver = new AgentCardResolver('https://agent.example.com');
*
* // Resolve the agent card
* const agentCard = await resolver.resolve();
* console.log('Agent name:', agentCard.name);
* console.log('Agent capabilities:', agentCard.capabilities);
* ```
*/
class AgentCardResolver {
/** @private Base URL of the agent server */
baseUrl;
/** @private Path to the agent card endpoint */
agentCardPath;
/** @private Cache time-to-live in milliseconds */
cacheTtl;
/** @private Request timeout in milliseconds */
timeout;
/** @private Circuit breaker for handling failures */
circuitBreaker;
/** @private Currently cached agent card, if any */
cache = null;
/**
* Creates a new agent card resolver
*
* @param baseUrl - Base URL of the agent server
* @param options - Configuration options
*/
constructor(baseUrl, options = {}) {
this.baseUrl = baseUrl.replace(/\/+$/, '');
this.agentCardPath = options.agentCardPath || '/.well-known/agent.json';
this.cacheTtl = options.cacheTtl || 300000; // 5 minutes
this.timeout = options.timeout || 5000;
// Initialize circuit breaker for reliability
this.circuitBreaker = new circuit_breaker_1.CircuitBreaker({
failureThreshold: 3,
successThreshold: 2,
timeout: 10000
});
}
/**
* Resolves agent card, using cache if available and not expired
*
* This method first checks if there is a valid cached agent card.
* If the cache is valid, it returns the cached card immediately.
* Otherwise, it fetches a fresh agent card from the server and
* updates the cache.
*
* @returns Promise resolving to the agent card
* @throws Error if fetching the agent card fails
*
* @example
* ```typescript
* const agentCard = await resolver.resolve();
* console.log('Agent name:', agentCard.name);
* ```
*/
async resolve() {
// Use cache if available and not expired
if (this.cache && this.cache.expiresAt > Date.now()) {
return this.cache.card;
}
// Fetch fresh card and update cache
const card = await this.fetchAgentCard();
this.cache = {
card,
expiresAt: Date.now() + this.cacheTtl
};
return card;
}
/**
* Force fresh fetch of agent card, bypassing cache
*
* This method always fetches a fresh agent card from the server,
* regardless of whether there is a valid cached card. It then
* updates the cache with the new card.
*
* @returns Promise resolving to the fresh agent card
* @throws Error if fetching the agent card fails
*
* @example
* ```typescript
* // Force a refresh of the agent card
* const freshCard = await resolver.refresh();
* console.log('Updated capabilities:', freshCard.capabilities);
* ```
*/
async refresh() {
// Fetch fresh card and update cache
const card = await this.fetchAgentCard();
this.cache = {
card,
expiresAt: Date.now() + this.cacheTtl
};
return card;
}
/**
* Fetches an agent card from the server
*
* This private method handles the actual HTTP request to fetch the agent card.
* It uses the circuit breaker pattern to prevent cascading failures and
* implements timeout handling for reliability.
*
* @returns Promise resolving to the fetched agent card
* @throws Error if the HTTP request fails or times out
* @private
*/
async fetchAgentCard() {
const url = `${this.baseUrl}${this.agentCardPath}`;
// Use circuit breaker to prevent cascading failures
return this.circuitBreaker.execute(async () => {
const response = await fetch(url, {
signal: AbortSignal.timeout(this.timeout)
});
if (!response.ok) {
throw new Error(`Failed to fetch agent card: ${response.status}`);
}
return response.json();
});
}
}
exports.AgentCardResolver = AgentCardResolver;
//# sourceMappingURL=agent-card-resolver.js.map