@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
TypeScript
/**
* @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