Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ public interface AgentCardMapper {

AgentCardMapper INSTANCE = A2AMappers.getMapper(AgentCardMapper.class);

// Deprecated proto fields - not present in spec API (removed in 1.0.0)
@Mapping(target = "url", ignore = true)
@Mapping(target = "preferredTransport", ignore = true)
@Mapping(target = "additionalInterfaces", ignore = true)
@Mapping(target = "provider", source = "provider", conditionExpression = "java(domain.provider() != null)")
@Mapping(target = "documentationUrl", source = "documentationUrl", conditionExpression = "java(domain.documentationUrl() != null)")
@Mapping(target = "iconUrl", source = "iconUrl", conditionExpression = "java(domain.iconUrl() != null)")
@Mapping(target = "url", ignore = true) // Deprecated in proto, derived from supportedInterfaces[0]
@Mapping(target = "preferredTransport", ignore = true) // Deprecated in proto, derived from supportedInterfaces[0]
@Mapping(target = "additionalInterfaces", ignore = true) // Deprecated in proto, use supportedInterfaces instead
io.a2a.grpc.AgentCard toProto(io.a2a.spec.AgentCard domain);

@Mapping(target = "provider", source = "provider", conditionExpression = "java(proto.hasProvider())")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public interface TaskStatusUpdateEventMapper {
/**
* Converts domain TaskStatusUpdateEvent to proto.
* Uses declarative mapping with CommonFieldMapper for metadata conversion.
* Note: MapStruct derives property "final" from domain's isFinal() getter (strips "is" prefix).
*/
@Mapping(target = "metadata", source = "metadata", qualifiedByName = "metadataToProto")
@Mapping(target = "final", source = "final")
Expand Down
22 changes: 22 additions & 0 deletions spec/src/main/java/io/a2a/json/JsonUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@

import static io.a2a.json.JsonUtil.JSONRPCErrorTypeAdapter.THROWABLE_MARKER_FIELD;

/**
* Utility class for JSON operations.
*/
public class JsonUtil {

private static GsonBuilder createBaseGsonBuilder() {
Expand Down Expand Up @@ -86,6 +89,15 @@ private static GsonBuilder createBaseGsonBuilder() {
.registerTypeHierarchyAdapter(StreamingEventKind.class, new StreamingEventKindTypeAdapter())
.create();

/**
* Deserializes JSON string to an object of the specified class.
*
* @param <T> the type of the object to deserialize to
* @param json the JSON string to parse
* @param classOfT the class of the object to deserialize to
* @return the deserialized object
* @throws JsonProcessingException if JSON parsing fails
*/
public static <T> T fromJson(String json, Class<T> classOfT) throws JsonProcessingException {
try {
return OBJECT_MAPPER.fromJson(json, classOfT);
Expand All @@ -94,6 +106,15 @@ public static <T> T fromJson(String json, Class<T> classOfT) throws JsonProcessi
}
}

/**
* Deserializes JSON string to an object of the specified type.
*
* @param <T> the type of the object to deserialize to
* @param json the JSON string to parse
* @param type the type of the object to deserialize to (supports generics)
* @return the deserialized object
* @throws JsonProcessingException if JSON parsing fails
*/
public static <T> T fromJson(String json, Type type) throws JsonProcessingException {
try {
return OBJECT_MAPPER.fromJson(json, type);
Expand All @@ -110,6 +131,7 @@ public static <T> T fromJson(String json, Type type) throws JsonProcessingExcept
*
* @param data the object to serialize
* @return JSON string representation of the object
* @throws JsonProcessingException if conversion fails
*/
public static String toJson(Object data) throws JsonProcessingException {
try {
Expand Down
7 changes: 7 additions & 0 deletions spec/src/main/java/io/a2a/spec/A2AClientHTTPError.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,14 @@
* @see <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status">HTTP Status Codes</a>
*/
public class A2AClientHTTPError extends A2AClientError {
/**
* The HTTP status code.
*/
private final int code;

/**
* The error message.
*/
private final String message;

/**
Expand Down
50 changes: 35 additions & 15 deletions spec/src/main/java/io/a2a/spec/AgentCard.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
* <p>
* This class is immutable and uses the Builder pattern for construction to handle the mix of
* required and optional fields defined by the specification.
* <p>
* <b>Important:</b> The {@link #supportedInterfaces()} field specifies how clients can
* communicate with the agent. Each entry combines a protocol binding (e.g., "JSONRPC",
* "GRPC") with a URL endpoint. The first entry in the list is the preferred interface.
*
* @param name the human-readable name of the agent (required)
* @param description a brief description of the agent's purpose and functionality (required)
Expand All @@ -32,9 +36,10 @@
* @param securitySchemes map of security scheme names to their definitions (optional)
* @param security list of security requirements for accessing the agent (optional)
* @param iconUrl URL to an icon representing the agent (optional)
* @param supportedInterfaces ordered list of supported interfaces. First entry is preferred. (required)
* @param supportedInterfaces ordered list of protocol+URL interface combinations; first entry is preferred (required)
* @param protocolVersion the version of the A2A Protocol this agent implements (defaults to {@link #DEFAULT_PROTOCOL_VERSION})
* @param signatures digital signatures verifying the authenticity of the agent card (optional)
* @see AgentInterface
* @see <a href="https://a2a-protocol.org/latest/">A2A Protocol Specification</a>
*/
public record AgentCard(
Expand All @@ -61,6 +66,22 @@ public record AgentCard(
/**
* Compact constructor that validates required fields and sets defaults.
*
* @param name the name parameter (see class-level JavaDoc)
* @param description the description parameter (see class-level JavaDoc)
* @param provider the provider parameter (see class-level JavaDoc)
* @param version the version parameter (see class-level JavaDoc)
* @param documentationUrl the documentationUrl parameter (see class-level JavaDoc)
* @param capabilities the capabilities parameter (see class-level JavaDoc)
* @param defaultInputModes the defaultInputModes parameter (see class-level JavaDoc)
* @param defaultOutputModes the defaultOutputModes parameter (see class-level JavaDoc)
* @param skills the skills parameter (see class-level JavaDoc)
* @param supportsExtendedAgentCard the supportsExtendedAgentCard parameter (see class-level JavaDoc)
* @param securitySchemes the securitySchemes parameter (see class-level JavaDoc)
* @param security the security parameter (see class-level JavaDoc)
* @param iconUrl the iconUrl parameter (see class-level JavaDoc)
* @param supportedInterfaces the supportedInterfaces parameter (see class-level JavaDoc)
* @param protocolVersion the protocolVersion parameter (see class-level JavaDoc)
* @param signatures the signatures parameter (see class-level JavaDoc)
* @throws IllegalArgumentException if any required field is null
*/
public AgentCard {
Expand All @@ -78,17 +99,6 @@ public record AgentCard(
}
}

/**
* Returns the list of additional interfaces.
*
* @return the list of supported interfaces
* @deprecated Use {@link #supportedInterfaces()} instead. This field has been renamed to 'supportedInterfaces'.
*/
@Deprecated(since = "0.4.0", forRemoval = true)
public List<AgentInterface> additionalInterfaces() {
return supportedInterfaces;
}

/**
* Create a new Builder
*
Expand Down Expand Up @@ -362,11 +372,21 @@ public Builder iconUrl(String iconUrl) {
}

/**
* Sets the ordered list of supported interfaces (first entry is preferred).
* Sets the ordered list of supported protocol interfaces (first entry is preferred).
* <p>
* Each interface defines a combination of protocol binding (e.g., "JSONRPC", "GRPC", "REST")
* and URL endpoint for accessing the agent. This is the primary field for declaring how
* clients can communicate with the agent as of protocol version 1.0.0.
* <p>
* Each interface defines a combination of protocol binding and URL for accessing the agent.
* Example:
* <pre>{@code
* .supportedInterfaces(List.of(
* new AgentInterface("JSONRPC", "http://localhost:9999"),
* new AgentInterface("GRPC", "grpc://localhost:9090")
* ))
* }</pre>
*
* @param supportedInterfaces the ordered list of supported interfaces (optional)
* @param supportedInterfaces the ordered list of supported interfaces (required)
* @return this builder for method chaining
* @see AgentInterface
*/
Expand Down
3 changes: 3 additions & 0 deletions spec/src/main/java/io/a2a/spec/AgentCardSignature.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ public record AgentCardSignature(Map<String, Object> header, @SerializedName("pr
/**
* Compact constructor that validates required fields.
*
* @param header the header parameter (see class-level JavaDoc)
* @param protectedHeader the protectedHeader parameter (see class-level JavaDoc)
* @param signature the signature parameter (see class-level JavaDoc)
* @throws IllegalArgumentException if protectedHeader or signature is null
*/
public AgentCardSignature {
Expand Down
4 changes: 4 additions & 0 deletions spec/src/main/java/io/a2a/spec/AgentExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ public record AgentExtension (String description, Map<String, Object> params, bo
/**
* Compact constructor that validates required fields.
*
* @param description the description parameter (see class-level JavaDoc)
* @param params the params parameter (see class-level JavaDoc)
* @param required the required parameter (see class-level JavaDoc)
* @param uri the uri parameter (see class-level JavaDoc)
* @throws IllegalArgumentException if uri is null
*/
public AgentExtension {
Expand Down
13 changes: 11 additions & 2 deletions spec/src/main/java/io/a2a/spec/AgentInterface.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
* are JSONRPC, GRPC, and HTTP+JSON.
* <p>
* Agents may support multiple interfaces to allow flexibility in how clients communicate.
* The {@link AgentCard} includes a primary interface (url + preferredTransport) and may
* list additional interfaces for alternative access methods.
* The {@link AgentCard#supportedInterfaces()} field contains an ordered list of interfaces,
* with the first entry being the preferred method for accessing the agent.
* <p>
* This class is immutable.
*
Expand All @@ -29,6 +29,9 @@ public record AgentInterface(String protocolBinding, String url, String tenant)
/**
* Compact constructor that validates required fields.
*
* @param protocolBinding the protocolBinding parameter (see class-level JavaDoc)
* @param url the url parameter (see class-level JavaDoc)
* @param tenant the tenant parameter (see class-level JavaDoc)
* @throws IllegalArgumentException if protocolBinding or url is null
*/
public AgentInterface {
Expand All @@ -37,6 +40,12 @@ public record AgentInterface(String protocolBinding, String url, String tenant)
Assert.checkNotNullParam("tenant", tenant);
}

/**
* Convenience constructor for creating an AgentInterface without a tenant.
*
* @param protocolBinding the protocol binding (see class-level JavaDoc)
* @param url the endpoint URL (see class-level JavaDoc)
*/
public AgentInterface(String protocolBinding, String url) {
this(protocolBinding, url, "");
}
Expand Down
2 changes: 2 additions & 0 deletions spec/src/main/java/io/a2a/spec/AgentProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public record AgentProvider(String organization, String url) {
/**
* Compact constructor that validates required fields.
*
* @param organization the organization parameter (see class-level JavaDoc)
* @param url the url parameter (see class-level JavaDoc)
* @throws IllegalArgumentException if organization or url is null
*/
public AgentProvider {
Expand Down
8 changes: 8 additions & 0 deletions spec/src/main/java/io/a2a/spec/AgentSkill.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ public record AgentSkill(String id, String name, String description, List<String
/**
* Compact constructor that validates required fields.
*
* @param id the id parameter (see class-level JavaDoc)
* @param name the name parameter (see class-level JavaDoc)
* @param description the description parameter (see class-level JavaDoc)
* @param tags the tags parameter (see class-level JavaDoc)
* @param examples the examples parameter (see class-level JavaDoc)
* @param inputModes the inputModes parameter (see class-level JavaDoc)
* @param outputModes the outputModes parameter (see class-level JavaDoc)
* @param security the security parameter (see class-level JavaDoc)
* @throws IllegalArgumentException if id, name, description, or tags is null
*/
public AgentSkill {
Expand Down
6 changes: 6 additions & 0 deletions spec/src/main/java/io/a2a/spec/Artifact.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ public record Artifact(String artifactId, String name, String description, List<
/**
* Compact constructor that validates required fields.
*
* @param artifactId the artifactId parameter (see class-level JavaDoc)
* @param name the name parameter (see class-level JavaDoc)
* @param description the description parameter (see class-level JavaDoc)
* @param parts the parts parameter (see class-level JavaDoc)
* @param metadata the metadata parameter (see class-level JavaDoc)
* @param extensions the extensions parameter (see class-level JavaDoc)
* @throws IllegalArgumentException if artifactId or parts is null, or if parts is empty
*/
public Artifact {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
*/
public class AuthenticatedExtendedCardNotConfiguredError extends JSONRPCError {

/**
* Constructs an error for agents that don't support authenticated extended card retrieval.
*
* @param code the error code
* @param message the error message
* @param data additional error data
*/
public AuthenticatedExtendedCardNotConfiguredError(
Integer code,
String message,
Expand Down
2 changes: 2 additions & 0 deletions spec/src/main/java/io/a2a/spec/AuthenticationInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public record AuthenticationInfo(List<String> schemes, String credentials) {
/**
* Compact constructor that validates required fields.
*
* @param schemes the schemes parameter (see class-level JavaDoc)
* @param credentials the credentials parameter (see class-level JavaDoc)
* @throws IllegalArgumentException if schemes is null
*/
public AuthenticationInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public record AuthorizationCodeOAuthFlow(String authorizationUrl, String refresh
/**
* Compact constructor that validates required fields.
*
* @param authorizationUrl the authorizationUrl parameter (see class-level JavaDoc)
* @param refreshUrl the refreshUrl parameter (see class-level JavaDoc)
* @param scopes the scopes parameter (see class-level JavaDoc)
* @param tokenUrl the tokenUrl parameter (see class-level JavaDoc)
* @throws IllegalArgumentException if authorizationUrl, scopes, or tokenUrl is null
*/
public AuthorizationCodeOAuthFlow {
Expand Down
13 changes: 2 additions & 11 deletions spec/src/main/java/io/a2a/spec/CancelTaskRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ private Builder() {
* @param jsonrpc the JSON-RPC version (optional, defaults to "2.0")
* @return this builder for method chaining
*/

public CancelTaskRequest.Builder jsonrpc(String jsonrpc) {
this.jsonrpc = jsonrpc;
return this;
Expand All @@ -95,23 +96,13 @@ public CancelTaskRequest.Builder id(Object id) {
return this;
}

/**
* Sets the JSON-RPC method name.
*
* @param method the method name (should be "CancelTask")
* @return this builder for method chaining
* @deprecated
*/
public CancelTaskRequest.Builder method(String method) {
return this;
}

/**
* Sets the request parameters containing the task ID to cancel.
*
* @param params the request parameters (required)
* @return this builder for method chaining
*/

public CancelTaskRequest.Builder params(TaskIdParams params) {
this.params = params;
return this;
Expand Down
20 changes: 20 additions & 0 deletions spec/src/main/java/io/a2a/spec/CancelTaskResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,35 @@

public final class CancelTaskResponse extends JSONRPCResponse<Task> {

/**
* Constructs a CancelTaskResponse with full parameters.
*
* @param jsonrpc the JSON-RPC version
* @param id the request ID
* @param result the task result
* @param error the error if any
*/
public CancelTaskResponse(String jsonrpc, Object id, Task result, JSONRPCError error) {
super(jsonrpc, id, result, error, Task.class);
}

/**
* Constructs a CancelTaskResponse with an error.
*
* @param id the request ID
* @param error the error
*/
public CancelTaskResponse(Object id, JSONRPCError error) {
this(null, id, null, error);
}


/**
* Constructs a CancelTaskResponse with a successful result.
*
* @param id the request ID
* @param result the task result
*/
public CancelTaskResponse(Object id, Task result) {
this(null, id, result, null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ public record ClientCredentialsOAuthFlow(String refreshUrl, Map<String, String>
/**
* Compact constructor that validates required fields.
*
* @param refreshUrl the refreshUrl parameter (see class-level JavaDoc)
* @param scopes the scopes parameter (see class-level JavaDoc)
* @param tokenUrl the tokenUrl parameter (see class-level JavaDoc)
* @throws IllegalArgumentException if scopes or tokenUrl is null
*/
public ClientCredentialsOAuthFlow {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@
*/
public class ContentTypeNotSupportedError extends JSONRPCError {

/**
* Constructs a content type not supported error.
*
* @param code the error code
* @param message the error message
* @param data additional error data
*/
public ContentTypeNotSupportedError(Integer code, String message, Object data) {
super(defaultIfNull(code, CONTENT_TYPE_NOT_SUPPORTED_ERROR_CODE),
defaultIfNull(message, "Incompatible content types"),
Expand Down
Loading