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

362 lines 13.3 kB
/** * @module HttpClient * @description Low-level HTTP client for communicating with A2A protocol servers */ import { type AgentCard, type Task, type MessagePart, type PushNotificationConfig, type Artifact, JsonRpcStreamResponse } from '@dexwox-labs/a2a-core'; /** * Configuration options for the HTTP client * * These options control how the HTTP client connects to and communicates with * A2A protocol servers, including timeouts, headers, and authentication. * * @example * ```typescript * const options: HttpClientOptions = { * baseUrl: 'https://a2a-server.example.com', * timeout: 10000, // 10 seconds * headers: { * 'X-API-Key': 'your-api-key' * }, * agentCard: { * cacheTtl: 600000 // 10 minutes * }, * pushAuth: { * token: 'initial-auth-token', * refresh: async () => { * // Get a new token from your auth service * return 'new-auth-token'; * } * } * }; * ``` */ export interface HttpClientOptions { /** * Base URL for API endpoints (e.g. 'https://api.example.com/v1') * This is the root URL where all A2A protocol requests will be sent */ baseUrl: string; /** * Request timeout in milliseconds (default: 5000) * After this duration, requests will be aborted and an error thrown */ timeout?: number; /** * Additional HTTP headers to include with every request * Useful for authentication, tracking, and other custom headers */ headers?: Record<string, string>; /** * Options for agent card resolution and caching * Controls how the client discovers and caches agent information */ agentCard?: { /** Path to agent card (default: '/.well-known/agent.json') */ path?: string; /** Cache TTL in milliseconds (default: 300000 - 5 minutes) */ cacheTtl?: number; }; /** * Push notification authentication configuration * Used for authenticating with push notification endpoints */ pushAuth?: { /** Auth token for push notifications */ token?: string; /** Auth token refresh callback that returns a new token when needed */ refresh?: () => Promise<string>; }; } /** * Low-level HTTP client for communicating with A2A protocol servers * * This class provides the core HTTP communication layer for the A2A SDK, * handling JSON-RPC requests, streaming, and agent card resolution. * * @example * ```typescript * const httpClient = new A2AHttpClient({ * baseUrl: 'https://a2a-server.example.com' * }); * * // Discover available agents * const agents = await httpClient.discover(); * console.log('Available agents:', agents); * * // Send a message to an agent * const messageId = await httpClient.sendMessage([ * { type: 'text', content: 'Hello, agent!' } * ], 'assistant-agent'); * ``` */ export declare class A2AHttpClient { /** @private Configuration options for the client */ private readonly options; /** @private Circuit breaker for handling failures */ private readonly circuitBreaker; /** @private Resolver for agent card information */ private readonly agentCardResolver; /** @private Default circuit breaker configuration */ private static readonly DEFAULT_CIRCUIT_BREAKER_OPTIONS; /** * Creates a new A2A HTTP client instance * * Initializes the HTTP client with the provided options, setting up the circuit breaker * and agent card resolver. Default values are applied for any missing options. * * @param options - Configuration options for the client * * @example * ```typescript * // Basic configuration * const client = new A2AHttpClient({ * baseUrl: 'https://a2a-server.example.com' * }); * * // Advanced configuration * const advancedClient = new A2AHttpClient({ * baseUrl: 'https://a2a-server.example.com', * timeout: 10000, * headers: { * 'Authorization': 'Bearer token123', * 'X-Custom-Header': 'custom-value' * }, * agentCard: { * path: '/custom-agent-path.json', * cacheTtl: 600000 // 10 minutes * } * }); * ``` */ constructor(options: HttpClientOptions); /** * Gets the resolved agent card for the connected server * * Retrieves the agent card from the server, which contains metadata about * the agent's capabilities, name, and other information. Results are cached * according to the configured TTL. * * @returns Promise resolving to the agent card * @throws {A2ANetworkError} If there's a network issue contacting the server * * @example * ```typescript * const agentCard = await httpClient.getAgentCard(); * console.log(`Connected to agent: ${agentCard.name}`); * console.log(`Agent capabilities: ${agentCard.capabilities.join(', ')}`); * ``` */ getAgentCard(): Promise<AgentCard>; /** * Refreshes the agent card cache * * Forces a refresh of the cached agent card information, bypassing the TTL. * This is useful when you know the agent's capabilities may have changed. * * @returns Promise resolving to the refreshed agent card * @throws {A2ANetworkError} If there's a network issue contacting the server * * @example * ```typescript * // Force a refresh of the agent card * const refreshedCard = await httpClient.refreshAgentCard(); * console.log('Updated capabilities:', refreshedCard.capabilities); * ``` */ refreshAgentCard(): Promise<AgentCard>; /** * Discovers available agents matching an optional capability filter * * This method queries the A2A network for available agents. If a capability * is specified, only agents that support that capability will be returned. * * @param capability - Optional capability filter (e.g., 'text-generation', 'image-generation') * @returns Promise resolving to an array of matching agent cards * @throws {A2ANetworkError} If there's a network issue contacting the server * @throws {A2AValidationError} If the capability filter is invalid * * @example * ```typescript * // Get all available agents * const allAgents = await httpClient.discover(); * console.log(`Found ${allAgents.length} agents`); * * // Get only agents with text generation capability * const textAgents = await httpClient.discover('text-generation'); * console.log(`Found ${textAgents.length} text generation agents`); * ``` */ discover(capability?: string): Promise<AgentCard[]>; /** * Gets task details by ID * * Retrieves the current state and details of a task by its ID. This method * fetches the complete task object including status, input, output, and any * error information. * * @param taskId - The ID of the task to retrieve * @returns Promise resolving to the complete task object * @throws {A2ANetworkError} If there's a network issue contacting the server * @throws {A2AValidationError} If the task ID is invalid or not found * * @example * ```typescript * try { * const task = await httpClient.getTask('task-123'); * console.log(`Task status: ${task.status}`); * * if (task.status === 'completed') { * console.log('Task output:', task.output); * } else if (task.status === 'failed') { * console.error('Task failed:', task.error); * } * } catch (error) { * console.error('Error retrieving task:', error.message); * } * ``` */ getTask(taskId: string): Promise<Task>; /** * Sends a task for execution * * Submits a task to the A2A server for execution. The task can contain * input data, target agent information, and other parameters needed for * execution. * * @param task - The task object to execute * @returns Promise resolving to the updated task with initial status * @throws {A2ANetworkError} If there's a network issue contacting the server * @throws {A2AValidationError} If the task is invalid * * @example * ```typescript * const task = { * id: 'task-' + Date.now(), * name: 'Weather Analysis', * agentId: 'weather-agent', * status: 'submitted', * input: { location: 'New York', days: 5 }, * createdAt: new Date().toISOString(), * updatedAt: new Date().toISOString() * }; * * const submittedTask = await httpClient.sendTask(task); * console.log(`Task submitted with ID: ${submittedTask.id}`); * console.log(`Initial status: ${submittedTask.status}`); * ``` */ sendTask(task: Task): Promise<Task>; /** * Cancels a running task * @param taskId Task ID to cancel * @returns Promise resolving to updated Task * @throws A2AError if cancellation fails */ cancelTask(taskId: string): Promise<Task>; /** * Gets push notification configuration for a task * @param taskId Task ID to get config for * @returns Promise resolving to PushNotificationConfig * @throws A2AError if config retrieval fails */ getPushNotificationConfig(taskId: string): Promise<PushNotificationConfig>; /** * Sets push notification configuration for a task * @param taskId Task ID to configure * @param config Push notification configuration * @returns Promise resolving to updated PushNotificationConfig * @throws A2AError if configuration fails */ setPushNotificationConfig(taskId: string, config: PushNotificationConfig): Promise<PushNotificationConfig>; /** * Refreshes the push notification auth token * @returns Promise resolving to new token * @throws A2AError if refresh fails */ refreshPushAuthToken(): Promise<string>; private createStreamRequest; private processStream; private processBuffer; private processEventLine; /** * Streams task execution events via Server-Sent Events (SSE) * @param task Task to execute * @param onEvent Callback for processing stream events * @returns Promise that resolves when stream completes * @throws A2AError if streaming fails to start */ streamTask(task: Task, onEvent: (event: JsonRpcStreamResponse) => void, options?: { lastEventId?: string; onResubscribe?: (newTask: Task) => void; }): Promise<void>; private isRecoverableError; private resubscribeTask; /** * Sends a message to an agent * @param parts Array of message parts (text/file/data) * @param agentId Target agent ID * @returns Promise resolving to message ID * @throws A2AError if message fails to send */ /** * Uploads an artifact to the server * @param artifact Artifact data to upload * @returns Promise resolving to artifact ID * @throws A2AError if upload fails */ uploadArtifact(artifact: Artifact): Promise<string>; /** * Downloads an artifact from the server * @param artifactId ID of artifact to download * @returns Promise resolving to artifact data * @throws A2AError if download fails */ downloadArtifact(artifactId: string): Promise<Artifact>; /** * Sends a message to an agent * * This method sends a message composed of one or more message parts to a * specified agent. Message parts can be text, files, or structured data. * * @param parts - Array of message parts to send (text, file, data, etc.) * @param agentId - ID of the target agent to receive the message * @returns Promise resolving to the message ID assigned by the server * @throws {A2ANetworkError} If there's a network issue contacting the server * @throws {A2AValidationError} If the message parts or agent ID are invalid * * @example * ```typescript * // Send a simple text message * const textMessageId = await httpClient.sendMessage([ * { type: 'text', content: 'Hello, agent!' } * ], 'assistant-agent'); * * // Send a message with multiple parts * const multipartMessageId = await httpClient.sendMessage([ * { type: 'text', content: 'Here is the data you requested' }, * { * type: 'data', * content: { temperature: 72, humidity: 65 }, * schema: 'weather-data' * } * ], 'weather-agent'); * ``` */ sendMessage(parts: MessagePart[], agentId: string): Promise<string>; private normalizeError; /** * Sends a JSON-RPC request to the A2A server * * This is the core method that handles all communication with the A2A server. * It uses the circuit breaker pattern to prevent cascading failures and * implements timeout handling. * * @param request - JSON-RPC request object to send * @returns Promise resolving to the JSON-RPC response * @throws Error if the HTTP request fails or times out * @template T - Expected response result type * @internal */ private sendRequest; } //# sourceMappingURL=http-client.d.ts.map