Skip to content

Commit 48fcbbd

Browse files
committed
Update docs again.
1 parent b6419a0 commit 48fcbbd

31 files changed

+1049
-563
lines changed

packages/a2a_dart/lib/src/client/a2a_client.dart

Lines changed: 122 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,39 @@ import 'a2a_exception.dart';
1717
import 'http_transport.dart';
1818
import 'transport.dart';
1919

20-
/// A client for interacting with an A2A server.
20+
/// A client for interacting with an A2A (Agent-to-Agent) server.
2121
///
2222
/// This class provides methods for all the RPC calls defined in the A2A
2323
/// specification. It handles the JSON-RPC 2.0 protocol and uses a [Transport]
24-
/// to communicate with the server.
24+
/// instance to communicate with the server, which defaults to [HttpTransport].
2525
class A2AClient {
26-
/// The URL of the A2A server.
26+
/// The base URL of the A2A server.
2727
final String url;
2828

2929
final Transport _transport;
3030
final Logger? _log;
3131

32-
/// Creates an [A2AClient].
32+
/// Creates an [A2AClient] instance.
3333
///
34-
/// The [url] is the base URL of the A2A server.
34+
/// The [url] parameter is required and specifies the base URL of the A2A
35+
/// server (e.g., `http://localhost:8000`).
3536
///
36-
/// The [transport] is the transport to use for communication. If not
37-
/// provided, an [HttpTransport] will be used.
37+
/// An optional [transport] can be provided to customize the communication
38+
/// layer. If omitted, an [HttpTransport] is created using the provided [url].
3839
///
39-
/// The [log] is the logger to use for logging.
40+
/// An optional [log] instance can be provided for logging client activities.
4041
A2AClient({required this.url, Transport? transport, Logger? log})
4142
: _transport = transport ?? HttpTransport(url: url, log: log),
4243
_log = log;
4344

44-
/// Fetches the agent card from the server.
45+
/// Fetches the public agent card from the server.
4546
///
46-
/// The agent card contains metadata about the agent. This is typically
47-
/// requested from the `/.well-known/agent-card.json` endpoint.
47+
/// The agent card contains metadata about the agent, such as its capabilities
48+
/// and security schemes. This method typically requests the card from the
49+
/// `/.well-known/agent-card.json` endpoint on the server.
50+
///
51+
/// Returns an [AgentCard] object.
52+
/// Throws an [A2AException] if the request fails or the response is invalid.
4853
Future<AgentCard> getAgentCard() async {
4954
_log?.info('Fetching agent card...');
5055
final response = await _transport.get('/.well-known/agent-card.json');
@@ -54,9 +59,13 @@ class A2AClient {
5459

5560
/// Fetches the authenticated extended agent card from the server.
5661
///
57-
/// This method is used to get a more detailed agent card that may be
58-
/// available to authenticated users. It sends an `Authorization` header
59-
/// with the given [token].
62+
/// This method retrieves a potentially more detailed [AgentCard] that is only
63+
/// available to authenticated users. It includes an `Authorization` header
64+
/// with the provided Bearer [token] in the request to
65+
/// `/.well-known/agent-card.json`.
66+
///
67+
/// Returns an [AgentCard] object.
68+
/// Throws an [A2AException] if the request fails or the response is invalid.
6069
Future<AgentCard> getAuthenticatedExtendedCard(String token) async {
6170
_log?.info('Fetching authenticated agent card...');
6271
final response = await _transport.get(
@@ -67,13 +76,19 @@ class A2AClient {
6776
return AgentCard.fromJson(response);
6877
}
6978

70-
/// Sends a message to the agent for a single-shot interaction.
79+
/// Sends a message to the agent for a single-shot interaction via
80+
/// `message/send`.
7181
///
7282
/// This method is used for synchronous request/response interactions. The
73-
/// returned [Task] contains the initial state of the task. For long-running
74-
/// tasks, the client can poll the task status using [getTask].
83+
/// server is expected to process the [message] and return a result relatively
84+
/// quickly. The returned [Task] contains the initial state of the task as
85+
/// reported by the server.
86+
///
87+
/// For operations that are expected to take longer, consider using
88+
/// [messageStream] or polling the task status using [getTask].
7589
///
76-
/// Throws an [A2AException] if the server returns an error.
90+
/// Returns the initial [Task] state. Throws an [A2AException] if the server
91+
/// returns a JSON-RPC error.
7792
Future<Task> messageSend(Message message) async {
7893
_log?.info('Sending message: ${message.messageId}');
7994
final response = await _transport.send({
@@ -93,13 +108,17 @@ class A2AClient {
93108
return Task.fromJson(response['result'] as Map<String, Object?>);
94109
}
95110

96-
/// Sends a message to the agent and subscribes to real-time updates.
111+
/// Sends a message to the agent and subscribes to real-time updates via
112+
/// `message/stream`.
97113
///
98-
/// This method is used for streaming interactions with the agent. The
99-
/// returned stream will emit [Event] objects as they are received from the
100-
/// server via Server-Sent Events (SSE).
114+
/// This method is used for streaming interactions. The agent can send
115+
/// multiple updates over time. The returned stream emits [Event] objects as
116+
/// they are received from the server, typically using Server-Sent Events
117+
/// (SSE).
101118
///
102-
/// Throws an [A2AException] if the server returns an error in the stream.
119+
/// Returns a [Stream] of [Event] objects. The stream will emit an
120+
/// [A2AException] if the server sends a JSON-RPC error within the event
121+
/// stream.
103122
Stream<Event> messageStream(Message message) {
104123
_log?.info('Sending message for stream: ${message.messageId}');
105124
final stream = _transport.sendStream({
@@ -131,10 +150,13 @@ class A2AClient {
131150
);
132151
}
133152

134-
/// Retrieves the current state of a task from the server.
153+
/// Retrieves the current state of a task from the server using `tasks/get`.
135154
///
136-
/// This is typically used for polling the status of a task that was initiated
137-
/// with [messageSend].
155+
/// This method is used to poll the status of a task, identified by [taskId],
156+
/// that was previously initiated (e.g., via [messageSend]).
157+
///
158+
/// Returns the current [Task] state. Throws an [A2AException] if the server
159+
/// returns a JSON-RPC error (e.g., task not found).
138160
Future<Task> getTask(String taskId) async {
139161
_log?.info('Getting task: $taskId');
140162
final response = await _transport.send({
@@ -144,12 +166,23 @@ class A2AClient {
144166
'id': 0,
145167
});
146168
_log?.fine('Received response from tasks/get: $response');
169+
if (response.containsKey('error')) {
170+
final error = response['error'] as Map<String, Object?>;
171+
throw A2AException.jsonRpc(
172+
code: error['code'] as int,
173+
message: error['message'] as String,
174+
);
175+
}
147176
return Task.fromJson(response['result'] as Map<String, Object?>);
148177
}
149178

150-
/// Retrieves a list of tasks from the server.
179+
/// Retrieves a list of tasks from the server using `tasks/list`.
151180
///
152-
/// The optional [params] can be used to filter and paginate the results.
181+
/// The optional [params] of type [ListTasksParams] can be provided to filter,
182+
/// sort, and paginate the task list.
183+
///
184+
/// Returns a [ListTasksResult] containing the list of tasks and pagination
185+
/// info. Throws an [A2AException] if the server returns a JSON-RPC error.
153186
Future<ListTasksResult> listTasks([ListTasksParams? params]) async {
154187
_log?.info('Listing tasks...');
155188
final response = await _transport.send({
@@ -159,14 +192,24 @@ class A2AClient {
159192
'id': 0,
160193
});
161194
_log?.fine('Received response from tasks/list: $response');
195+
if (response.containsKey('error')) {
196+
final error = response['error'] as Map<String, Object?>;
197+
throw A2AException.jsonRpc(
198+
code: error['code'] as int,
199+
message: error['message'] as String,
200+
);
201+
}
162202
return ListTasksResult.fromJson(response['result'] as Map<String, Object?>);
163203
}
164204

165-
/// Requests the cancellation of an ongoing task.
205+
/// Requests the cancellation of an ongoing task using `tasks/cancel`.
166206
///
167-
/// The server will attempt to cancel the task, but success is not guaranteed.
168-
/// The returned [Task] will contain the state of the task after the
169-
/// cancellation request.
207+
/// The server will attempt to cancel the task identified by [taskId].
208+
/// Success is not guaranteed, as the task might have already completed or may
209+
/// not support cancellation.
210+
///
211+
/// Returns the updated [Task] state after the cancellation request.
212+
/// Throws an [A2AException] if the server returns a JSON-RPC error.
170213
Future<Task> cancelTask(String taskId) async {
171214
_log?.info('Canceling task: $taskId');
172215
final response = await _transport.send({
@@ -176,13 +219,25 @@ class A2AClient {
176219
'id': 0,
177220
});
178221
_log?.fine('Received response from tasks/cancel: $response');
222+
if (response.containsKey('error')) {
223+
final error = response['error'] as Map<String, Object?>;
224+
throw A2AException.jsonRpc(
225+
code: error['code'] as int,
226+
message: error['message'] as String,
227+
);
228+
}
179229
return Task.fromJson(response['result'] as Map<String, Object?>);
180230
}
181231

182-
/// Resubscribes to an SSE stream for an ongoing task.
232+
/// Resubscribes to an SSE stream for an ongoing task using
233+
/// `tasks/resubscribe`.
183234
///
184-
/// This can be used to reconnect to a stream after a disconnection. The
235+
/// This method allows a client to reconnect to the event stream of a task
236+
/// identified by [taskId], for instance, after a network interruption. The
185237
/// returned stream will emit subsequent [Event] objects for the task.
238+
///
239+
/// Returns a [Stream] of [Event] objects. The stream will emit an
240+
/// [A2AException] if the server returns a JSON-RPC error.
186241
Stream<Event> resubscribeToTask(String taskId) {
187242
_log?.info('Resubscribing to task: $taskId');
188243
return _transport
@@ -193,16 +248,31 @@ class A2AClient {
193248
})
194249
.map((data) {
195250
_log?.fine('Received event from stream: $data');
251+
if (data.containsKey('error')) {
252+
final error = data['error'] as Map<String, Object?>;
253+
throw A2AException.jsonRpc(
254+
code: error['code'] as int,
255+
message: error['message'] as String,
256+
);
257+
}
196258
return Event.fromJson(data);
197259
});
198260
}
199261

200-
/// Closes the underlying transport.
262+
/// Closes the underlying transport connection.
263+
///
264+
/// This should be called when the client is no longer needed to release
265+
/// resources.
201266
void close() {
202267
_transport.close();
203268
}
204269

205270
/// Sets or updates the push notification configuration for a task.
271+
///
272+
/// Uses the `tasks/pushNotificationConfig/set` method.
273+
///
274+
/// Returns the updated [TaskPushNotificationConfig].
275+
/// Throws an [A2AException] if the server returns a JSON-RPC error.
206276
Future<TaskPushNotificationConfig> setPushNotificationConfig(
207277
TaskPushNotificationConfig params,
208278
) async {
@@ -229,6 +299,12 @@ class A2AClient {
229299
}
230300

231301
/// Retrieves a specific push notification configuration for a task.
302+
///
303+
/// Uses the `tasks/pushNotificationConfig/get` method, identified by [taskId]
304+
/// and [configId].
305+
///
306+
/// Returns the requested [TaskPushNotificationConfig].
307+
/// Throws an [A2AException] if the server returns a JSON-RPC error.
232308
Future<TaskPushNotificationConfig> getPushNotificationConfig(
233309
String taskId,
234310
String configId,
@@ -255,7 +331,12 @@ class A2AClient {
255331
);
256332
}
257333

258-
/// Lists all push notification configurations for a task.
334+
/// Lists all push notification configurations for a given task.
335+
///
336+
/// Uses the `tasks/pushNotificationConfig/list` method, identified by [taskId].
337+
///
338+
/// Returns a List of [PushNotificationConfig] objects.
339+
/// Throws an [A2AException] if the server returns a JSON-RPC error.
259340
Future<List<PushNotificationConfig>> listPushNotificationConfigs(
260341
String taskId,
261342
) async {
@@ -287,6 +368,11 @@ class A2AClient {
287368
}
288369

289370
/// Deletes a specific push notification configuration for a task.
371+
///
372+
/// Uses the `tasks/pushNotificationConfig/delete` method, identified by [taskId]
373+
/// and [configId].
374+
///
375+
/// Throws an [A2AException] if the server returns a JSON-RPC error.
290376
Future<void> deletePushNotificationConfig(
291377
String taskId,
292378
String configId,

packages/a2a_dart/lib/src/client/a2a_exception.dart

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,61 @@ import 'package:freezed_annotation/freezed_annotation.dart';
77
part 'a2a_exception.freezed.dart';
88
part 'a2a_exception.g.dart';
99

10-
/// A sealed class for all A2A client-side exceptions.
10+
/// Base class for exceptions thrown by the A2A client.
11+
///
12+
/// This sealed class hierarchy represents different categories of errors
13+
/// that can occur during communication with an A2A server.
1114
@freezed
1215
sealed class A2AException with _$A2AException implements Exception {
13-
/// An exception that represents a JSON-RPC error from the server.
16+
/// Represents a JSON-RPC error returned by the server.
17+
///
18+
/// This exception is thrown when the server responds with a JSON-RPC error
19+
/// object, indicating a problem with the request as understood by the A2A
20+
/// protocol.
1421
const factory A2AException.jsonRpc({
15-
/// The JSON-RPC error code.
22+
/// The integer error code as defined by the JSON-RPC 2.0 specification
23+
/// or A2A-specific error codes.
1624
required int code,
1725

18-
/// The JSON-RPC error message.
26+
/// A human-readable string describing the error.
1927
required String message,
2028

21-
/// Optional data associated with the error.
29+
/// Optional additional data provided by the server about the error.
2230
Map<String, Object?>? data,
2331
}) = A2AJsonRpcException;
2432

25-
/// An exception that represents an HTTP error.
26-
const factory A2AException.http({required int statusCode, String? reason}) =
27-
A2AHttpException;
33+
/// Represents an error related to the HTTP transport layer.
34+
///
35+
/// This exception is thrown when an HTTP request fails with a non-2xx status
36+
/// code, and the issue is not a specific JSON-RPC error.
37+
const factory A2AException.http({
38+
/// The HTTP status code (e.g., 404, 500).
39+
required int statusCode,
2840

29-
/// An exception that represents a network error.
30-
const factory A2AException.network({required String message}) =
31-
A2ANetworkException;
41+
/// An optional human-readable reason phrase associated with the status
42+
/// code.
43+
String? reason,
44+
}) = A2AHttpException;
3245

33-
/// An exception that represents a parsing error.
46+
/// Represents a network connectivity issue.
47+
///
48+
/// This exception is thrown when a connection to the server cannot be
49+
/// established or is interrupted.
50+
const factory A2AException.network({
51+
/// A message describing the network error.
52+
required String message,
53+
}) = A2ANetworkException;
54+
55+
/// Represents an error during the parsing of a server response.
56+
///
57+
/// This exception is thrown if the client fails to parse the server's
58+
/// response, for example, due to malformed JSON.
3459
const factory A2AException.parsing({
35-
/// The error message.
60+
/// A message describing the parsing failure.
3661
required String message,
3762
}) = A2AParsingException;
3863

39-
/// Creates an [A2AException] from a JSON object.
64+
/// Deserializes an [A2AException] from a JSON object.
4065
factory A2AException.fromJson(Map<String, Object?> json) =>
4166
_$A2AExceptionFromJson(json);
4267
}

0 commit comments

Comments
 (0)