Skip to content

Commit 30d7ddd

Browse files
committed
feat: Add Javadoc for the client modules
1 parent 1277f24 commit 30d7ddd

File tree

16 files changed

+2248
-44
lines changed

16 files changed

+2248
-44
lines changed

client/base/src/main/java/io/a2a/A2A.java

Lines changed: 240 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,83 +16,210 @@
1616

1717

1818
/**
19-
* Constants and utility methods related to the A2A protocol.
19+
* Utility class providing convenience methods for working with the A2A Protocol.
20+
* <p>
21+
* This class offers static helper methods for common A2A operations:
22+
* <ul>
23+
* <li><b>Message creation:</b> Simplified construction of user and agent messages</li>
24+
* <li><b>Agent card retrieval:</b> Fetching agent metadata from URLs</li>
25+
* </ul>
26+
* <p>
27+
* These utilities simplify client code by providing concise alternatives to the builder
28+
* APIs for routine operations.
29+
* <p>
30+
* <b>Example usage:</b>
31+
* <pre>{@code
32+
* // Get agent card
33+
* AgentCard card = A2A.getAgentCard("http://localhost:9999");
34+
*
35+
* // Create and send a user message
36+
* Message userMsg = A2A.toUserMessage("What's the weather today?");
37+
* client.sendMessage(userMsg);
38+
*
39+
* // Create a message with context and task IDs
40+
* Message contextMsg = A2A.createUserTextMessage(
41+
* "Continue the conversation",
42+
* "session-123", // contextId
43+
* "task-456" // taskId
44+
* );
45+
* client.sendMessage(contextMsg);
46+
* }</pre>
47+
*
48+
* @see Message
49+
* @see AgentCard
50+
* @see io.a2a.client.Client
2051
*/
2152
public class A2A {
2253

2354
/**
24-
* Convert the given text to a user message.
55+
* Create a simple user message from text.
56+
* <p>
57+
* This is the most common way to create messages when sending requests to agents.
58+
* The message will have:
59+
* <ul>
60+
* <li>role: USER</li>
61+
* <li>parts: Single {@link io.a2a.spec.TextPart} with the provided text</li>
62+
* <li>Auto-generated message ID</li>
63+
* </ul>
64+
* <p>
65+
* Example:
66+
* <pre>{@code
67+
* Message msg = A2A.toUserMessage("Tell me a joke");
68+
* client.sendMessage(msg);
69+
* }</pre>
2570
*
26-
* @param text the message text
27-
* @return the user message
71+
* @param text the message text (required)
72+
* @return a user message with the specified text
73+
* @see #toUserMessage(String, String)
74+
* @see #createUserTextMessage(String, String, String)
2875
*/
2976
public static Message toUserMessage(String text) {
3077
return toMessage(text, Message.Role.USER, null);
3178
}
3279

3380
/**
34-
* Convert the given text to a user message.
81+
* Create a user message from text with a specific message ID.
82+
* <p>
83+
* Use this when you need to control the message ID for tracking or correlation purposes.
84+
* <p>
85+
* Example:
86+
* <pre>{@code
87+
* String messageId = UUID.randomUUID().toString();
88+
* Message msg = A2A.toUserMessage("Process this request", messageId);
89+
* // Store messageId for later correlation
90+
* client.sendMessage(msg);
91+
* }</pre>
3592
*
36-
* @param text the message text
93+
* @param text the message text (required)
3794
* @param messageId the message ID to use
38-
* @return the user message
95+
* @return a user message with the specified text and ID
96+
* @see #toUserMessage(String)
3997
*/
4098
public static Message toUserMessage(String text, String messageId) {
4199
return toMessage(text, Message.Role.USER, messageId);
42100
}
43101

44102
/**
45-
* Convert the given text to an agent message.
103+
* Create a simple agent message from text.
104+
* <p>
105+
* This is typically used in testing or when constructing agent responses programmatically.
106+
* Most client applications receive agent messages via {@link io.a2a.client.MessageEvent}
107+
* rather than creating them manually.
108+
* <p>
109+
* Example:
110+
* <pre>{@code
111+
* // Testing scenario
112+
* Message agentResponse = A2A.toAgentMessage("Here's the answer: 42");
113+
* }</pre>
46114
*
47-
* @param text the message text
48-
* @return the agent message
115+
* @param text the message text (required)
116+
* @return an agent message with the specified text
117+
* @see #toAgentMessage(String, String)
49118
*/
50119
public static Message toAgentMessage(String text) {
51120
return toMessage(text, Message.Role.AGENT, null);
52121
}
53122

54123
/**
55-
* Convert the given text to an agent message.
124+
* Create an agent message from text with a specific message ID.
125+
* <p>
126+
* Example:
127+
* <pre>{@code
128+
* Message agentResponse = A2A.toAgentMessage("Processing complete", "msg-789");
129+
* }</pre>
56130
*
57-
* @param text the message text
131+
* @param text the message text (required)
58132
* @param messageId the message ID to use
59-
* @return the agent message
133+
* @return an agent message with the specified text and ID
60134
*/
61135
public static Message toAgentMessage(String text, String messageId) {
62136
return toMessage(text, Message.Role.AGENT, messageId);
63137
}
64138

65139
/**
66140
* Create a user message with text content and optional context and task IDs.
141+
* <p>
142+
* This method is useful when continuing a conversation or working with a specific task:
143+
* <ul>
144+
* <li><b>contextId:</b> Links message to a conversation session</li>
145+
* <li><b>taskId:</b> Associates message with an existing task</li>
146+
* </ul>
147+
* <p>
148+
* Example - continuing a conversation:
149+
* <pre>{@code
150+
* // First message creates context
151+
* Message msg1 = A2A.toUserMessage("What's your name?");
152+
* client.sendMessage(msg1);
153+
* String contextId = ...; // Get from response
154+
*
155+
* // Follow-up message uses contextId
156+
* Message msg2 = A2A.createUserTextMessage(
157+
* "What else can you do?",
158+
* contextId,
159+
* null // no specific task
160+
* );
161+
* client.sendMessage(msg2);
162+
* }</pre>
163+
* <p>
164+
* Example - adding to an existing task:
165+
* <pre>{@code
166+
* Message msg = A2A.createUserTextMessage(
167+
* "Add this information too",
168+
* "session-123",
169+
* "task-456" // Continue working on this task
170+
* );
171+
* client.sendMessage(msg);
172+
* }</pre>
67173
*
68174
* @param text the message text (required)
69175
* @param contextId the context ID to use (optional)
70176
* @param taskId the task ID to use (optional)
71-
* @return the user message
177+
* @return a user message with the specified text, context, and task IDs
178+
* @see #createAgentTextMessage(String, String, String)
179+
* @see Message#contextId()
180+
* @see Message#taskId()
72181
*/
73182
public static Message createUserTextMessage(String text, String contextId, String taskId) {
74183
return toMessage(text, Message.Role.USER, null, contextId, taskId);
75184
}
76185

77186
/**
78187
* Create an agent message with text content and optional context and task IDs.
188+
* <p>
189+
* This is typically used in testing or when constructing agent responses programmatically.
79190
*
80191
* @param text the message text (required)
81192
* @param contextId the context ID to use (optional)
82193
* @param taskId the task ID to use (optional)
83-
* @return the agent message
194+
* @return an agent message with the specified text, context, and task IDs
195+
* @see #createUserTextMessage(String, String, String)
84196
*/
85197
public static Message createAgentTextMessage(String text, String contextId, String taskId) {
86198
return toMessage(text, Message.Role.AGENT, null, contextId, taskId);
87199
}
88200

89201
/**
90202
* Create an agent message with custom parts and optional context and task IDs.
203+
* <p>
204+
* This method allows creating messages with multiple parts (text, images, files, etc.)
205+
* instead of just simple text. Useful for complex agent responses or testing.
206+
* <p>
207+
* Example - message with text and image:
208+
* <pre>{@code
209+
* List<Part<?>> parts = List.of(
210+
* new TextPart("Here's a chart of the data:"),
211+
* new ImagePart("https://example.com/chart.png", "Chart showing sales data")
212+
* );
213+
* Message msg = A2A.createAgentPartsMessage(parts, "session-123", "task-456");
214+
* }</pre>
91215
*
92-
* @param parts the message parts (required)
216+
* @param parts the message parts (required, must not be empty)
93217
* @param contextId the context ID to use (optional)
94218
* @param taskId the task ID to use (optional)
95-
* @return the agent message
219+
* @return an agent message with the specified parts, context, and task IDs
220+
* @throws IllegalArgumentException if parts is null or empty
221+
* @see io.a2a.spec.Part
222+
* @see io.a2a.spec.TextPart
96223
*/
97224
public static Message createAgentPartsMessage(List<Part<?>> parts, String contextId, String taskId) {
98225
if (parts == null || parts.isEmpty()) {
@@ -130,56 +257,140 @@ private static Message toMessage(List<Part<?>> parts, Message.Role role, String
130257
}
131258

132259
/**
133-
* Get the agent card for an A2A agent.
260+
* Retrieve the agent card for an A2A agent.
261+
* <p>
262+
* This is the standard way to discover an agent's capabilities before creating a client.
263+
* The agent card is fetched from the well-known endpoint: {@code <agentUrl>/.well-known/agent-card.json}
264+
* <p>
265+
* Example:
266+
* <pre>{@code
267+
* // Get agent card
268+
* AgentCard card = A2A.getAgentCard("http://localhost:9999");
269+
*
270+
* // Check capabilities
271+
* System.out.println("Agent: " + card.name());
272+
* System.out.println("Supports streaming: " + card.capabilities().streaming());
273+
*
274+
* // Create client
275+
* Client client = Client.builder(card)
276+
* .withTransport(...)
277+
* .build();
278+
* }</pre>
134279
*
135280
* @param agentUrl the base URL for the agent whose agent card we want to retrieve
136281
* @return the agent card
137-
* @throws A2AClientError If an HTTP error occurs fetching the card
138-
* @throws A2AClientJSONError If the response body cannot be decoded as JSON or validated against the AgentCard schema
282+
* @throws io.a2a.spec.A2AClientError if an HTTP error occurs fetching the card
283+
* @throws io.a2a.spec.A2AClientJSONError if the response body cannot be decoded as JSON or validated against the AgentCard schema
284+
* @see #getAgentCard(A2AHttpClient, String)
285+
* @see #getAgentCard(String, String, java.util.Map)
286+
* @see AgentCard
139287
*/
140288
public static AgentCard getAgentCard(String agentUrl) throws A2AClientError, A2AClientJSONError {
141289
return getAgentCard(new JdkA2AHttpClient(), agentUrl);
142290
}
143291

144292
/**
145-
* Get the agent card for an A2A agent.
293+
* Retrieve the agent card using a custom HTTP client.
294+
* <p>
295+
* Use this variant when you need to customize HTTP behavior (timeouts, SSL configuration,
296+
* connection pooling, etc.).
297+
* <p>
298+
* Example:
299+
* <pre>{@code
300+
* A2AHttpClient customClient = new CustomHttpClient()
301+
* .withTimeout(Duration.ofSeconds(10))
302+
* .withSSLContext(mySSLContext);
303+
*
304+
* AgentCard card = A2A.getAgentCard(customClient, "https://secure-agent.com");
305+
* }</pre>
146306
*
147307
* @param httpClient the http client to use
148308
* @param agentUrl the base URL for the agent whose agent card we want to retrieve
149309
* @return the agent card
150-
* @throws A2AClientError If an HTTP error occurs fetching the card
151-
* @throws A2AClientJSONError If the response body cannot be decoded as JSON or validated against the AgentCard schema
310+
* @throws io.a2a.spec.A2AClientError if an HTTP error occurs fetching the card
311+
* @throws io.a2a.spec.A2AClientJSONError if the response body cannot be decoded as JSON or validated against the AgentCard schema
312+
* @see io.a2a.client.http.A2AHttpClient
152313
*/
153314
public static AgentCard getAgentCard(A2AHttpClient httpClient, String agentUrl) throws A2AClientError, A2AClientJSONError {
154315
return getAgentCard(httpClient, agentUrl, null, null);
155316
}
156317

157318
/**
158-
* Get the agent card for an A2A agent.
319+
* Retrieve the agent card with custom path and authentication.
320+
* <p>
321+
* Use this variant when:
322+
* <ul>
323+
* <li>The agent card is at a non-standard location</li>
324+
* <li>Authentication is required to access the agent card</li>
325+
* </ul>
326+
* <p>
327+
* Example with authentication:
328+
* <pre>{@code
329+
* Map<String, String> authHeaders = Map.of(
330+
* "Authorization", "Bearer my-api-token",
331+
* "X-API-Key", "my-api-key"
332+
* );
333+
*
334+
* AgentCard card = A2A.getAgentCard(
335+
* "https://secure-agent.com",
336+
* null, // Use default path
337+
* authHeaders
338+
* );
339+
* }</pre>
340+
* <p>
341+
* Example with custom path:
342+
* <pre>{@code
343+
* AgentCard card = A2A.getAgentCard(
344+
* "https://agent.com",
345+
* "api/v2/agent-info", // Custom path
346+
* null // No auth needed
347+
* );
348+
* // Fetches from: https://agent.com/api/v2/agent-info
349+
* }</pre>
159350
*
160351
* @param agentUrl the base URL for the agent whose agent card we want to retrieve
161352
* @param relativeCardPath optional path to the agent card endpoint relative to the base
162353
* agent URL, defaults to ".well-known/agent-card.json"
163354
* @param authHeaders the HTTP authentication headers to use
164355
* @return the agent card
165-
* @throws A2AClientError If an HTTP error occurs fetching the card
166-
* @throws A2AClientJSONError If the response body cannot be decoded as JSON or validated against the AgentCard schema
356+
* @throws io.a2a.spec.A2AClientError if an HTTP error occurs fetching the card
357+
* @throws io.a2a.spec.A2AClientJSONError if the response body cannot be decoded as JSON or validated against the AgentCard schema
167358
*/
168359
public static AgentCard getAgentCard(String agentUrl, String relativeCardPath, Map<String, String> authHeaders) throws A2AClientError, A2AClientJSONError {
169360
return getAgentCard(new JdkA2AHttpClient(), agentUrl, relativeCardPath, authHeaders);
170361
}
171362

172363
/**
173-
* Get the agent card for an A2A agent.
364+
* Retrieve the agent card with full customization options.
365+
* <p>
366+
* This is the most flexible variant, allowing customization of:
367+
* <ul>
368+
* <li>HTTP client implementation</li>
369+
* <li>Agent card endpoint path</li>
370+
* <li>Authentication headers</li>
371+
* </ul>
372+
* <p>
373+
* Example:
374+
* <pre>{@code
375+
* A2AHttpClient customClient = new CustomHttpClient();
376+
* Map<String, String> authHeaders = Map.of("Authorization", "Bearer token");
377+
*
378+
* AgentCard card = A2A.getAgentCard(
379+
* customClient,
380+
* "https://agent.com",
381+
* "custom/agent-card",
382+
* authHeaders
383+
* );
384+
* }</pre>
174385
*
175386
* @param httpClient the http client to use
176387
* @param agentUrl the base URL for the agent whose agent card we want to retrieve
177388
* @param relativeCardPath optional path to the agent card endpoint relative to the base
178389
* agent URL, defaults to ".well-known/agent-card.json"
179390
* @param authHeaders the HTTP authentication headers to use
180391
* @return the agent card
181-
* @throws A2AClientError If an HTTP error occurs fetching the card
182-
* @throws A2AClientJSONError If the response body cannot be decoded as JSON or validated against the AgentCard schema
392+
* @throws io.a2a.spec.A2AClientError if an HTTP error occurs fetching the card
393+
* @throws io.a2a.spec.A2AClientJSONError if the response body cannot be decoded as JSON or validated against the AgentCard schema
183394
*/
184395
public static AgentCard getAgentCard(A2AHttpClient httpClient, String agentUrl, String relativeCardPath, Map<String, String> authHeaders) throws A2AClientError, A2AClientJSONError {
185396
A2ACardResolver resolver = new A2ACardResolver(httpClient, agentUrl, "", relativeCardPath, authHeaders);

0 commit comments

Comments
 (0)