UNPKG

@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

152 lines 5.9 kB
"use strict"; /** * @module AgentClient * @description Client for interacting with A2A agents and their capabilities */ Object.defineProperty(exports, "__esModule", { value: true }); exports.AgentClient = void 0; const error_handler_1 = require("./utils/error-handler"); const http_utils_1 = require("./utils/http-utils"); /** * Client for discovering and interacting with A2A agents * * @example * ```typescript * const agentClient = new AgentClient({ baseUrl: 'https://a2a-server.example.com' }); * * // Get all available agents * const agents = await agentClient.resolveAgents(); * * // Get a specific agent by ID * const agent = await agentClient.getAgentCard('weather-agent'); * ``` */ class AgentClient { options; /** @private Cache for agent resolution results */ agentCache = null; /** @private Time-to-live for the agent cache in milliseconds */ cacheTTL = 300000; // 5 minutes /** * Creates a new AgentClient instance * @param options - Configuration options for the client */ constructor(options) { this.options = options; } /** * Resolves agent cards with caching * * This method discovers available agents from the A2A server. Results are cached * to improve performance and reduce network traffic. The cache can be bypassed * by setting forceRefresh to true. * * @param capability - Optional capability filter to find agents with specific capabilities * @param forceRefresh - Whether to bypass the cache and force a fresh request (default: false) * @returns Promise resolving to an array of matching AgentCards * @throws {A2ANetworkError} If there's a network issue contacting the server * @throws {A2AValidationError} If the server response is invalid * @throws {A2ATimeoutError} If the request times out * * @example * ```typescript * // Get all agents * const allAgents = await agentClient.resolveAgents(); * * // Get only agents with a specific capability * const weatherAgents = await agentClient.resolveAgents('weather-forecasting'); * * // Force a fresh request bypassing the cache * const freshAgents = await agentClient.resolveAgents(undefined, true); * ``` */ async resolveAgents(capability, forceRefresh = false) { // Return cached results if valid and not forcing refresh if (!forceRefresh && this.agentCache && Date.now() < this.agentCache.expiresAt) { return capability ? this.agentCache.agents.filter(a => a.capabilities.includes(capability)) : this.agentCache.agents; } const request = { jsonrpc: '2.0', method: 'discover', params: capability ? { capability } : undefined }; try { const response = await (0, http_utils_1.sendRequest)(this.options, request); this.agentCache = { agents: response.result.agents, expiresAt: Date.now() + this.cacheTTL, lastUpdated: Date.now() }; return response.result.agents; } catch (err) { if (err instanceof Error && err.message.includes('Network')) { // Return stale cache if available when network fails if (this.agentCache) { return capability ? this.agentCache.agents.filter(a => a.capabilities.includes(capability)) : this.agentCache.agents; } throw new error_handler_1.A2ANetworkError('Failed to resolve agents', { originalError: err, capability }); } throw (0, error_handler_1.normalizeError)(err); } } /** * Gets a specific agent's card by ID * * This method retrieves information about a specific agent by its ID. It uses * the resolveAgents method internally and filters the results to find the * requested agent. * * @param agentId - The ID of the agent to look up * @param forceRefresh - Whether to bypass the cache and force a fresh request (default: false) * @returns Promise resolving to the requested AgentCard * @throws {A2AValidationError} If the agent with the specified ID is not found * @throws {A2ANetworkError} If there's a network issue contacting the server * @throws {A2ATimeoutError} If the request times out * * @example * ```typescript * try { * const weatherAgent = await agentClient.getAgentCard('weather-agent'); * console.log(`Found agent: ${weatherAgent.name}`); * } catch (error) { * if (error.code === 'VALIDATION_ERROR') { * console.error('Agent not found'); * } else { * console.error('Error fetching agent:', error.message); * } * } * ``` */ async getAgentCard(agentId, forceRefresh = false) { try { const agents = await this.resolveAgents(undefined, forceRefresh); const agent = agents.find(a => a.id === agentId); if (!agent) { throw new error_handler_1.A2AValidationError('Agent not found', { agentId, availableAgents: agents.map(a => a.id) }); } return agent; } catch (err) { if (err instanceof Error && err.message.includes('timeout')) { throw new error_handler_1.A2ATimeoutError('Agent resolution timed out', { originalError: err, agentId }); } throw (0, error_handler_1.normalizeError)(err); } } } exports.AgentClient = AgentClient; //# sourceMappingURL=agent-client.js.map