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
2 changes: 1 addition & 1 deletion spec/src/main/java/io/a2a/json/JsonUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private static GsonBuilder createBaseGsonBuilder() {
* <p>
* Used throughout the SDK for consistent JSON serialization and deserialization.
*
* @see GsonBuilder
* @see JsonUtil#createBaseGsonBuilder()
*/
public static final Gson OBJECT_MAPPER = createBaseGsonBuilder()
.registerTypeHierarchyAdapter(Part.class, new PartTypeAdapter())
Expand Down
8 changes: 8 additions & 0 deletions spec/src/main/java/io/a2a/spec/A2AClientHTTPError.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ public class A2AClientHTTPError extends A2AClientError {
private final int code;
private final String message;

/**
* Creates a new HTTP client error with the specified status code and message.
*
* @param code the HTTP status code
* @param message the error message
* @param data additional error data (may be the response body)
* @throws IllegalArgumentException if code or message is null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The @throws documentation for the code parameter is misleading. Since code is a primitive int, it cannot be null. The corresponding check in the constructor body, Assert.checkNotNullParam("code", code), is also redundant because a primitive int cannot be null.

Please update the Javadoc to only mention message as being checked for nullity. For completeness, you might also consider removing the redundant null check for code from the constructor body.

Suggested change
* @throws IllegalArgumentException if code or message is null
* @throws IllegalArgumentException if message is null

*/
public A2AClientHTTPError(int code, String message, Object data) {
Assert.checkNotNullParam("code", code);
Assert.checkNotNullParam("message", message);
Expand Down
14 changes: 14 additions & 0 deletions spec/src/main/java/io/a2a/spec/A2AClientInvalidArgsError.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,27 @@
*/
public class A2AClientInvalidArgsError extends A2AClientError {

/**
* Creates a new invalid arguments error with no message.
*/
public A2AClientInvalidArgsError() {
}

/**
* Creates a new invalid arguments error with the specified message.
*
* @param message the error message
*/
public A2AClientInvalidArgsError(String message) {
super("Invalid arguments error: " + message);
}

/**
* Creates a new invalid arguments error with the specified message and cause.
*
* @param message the error message
* @param cause the underlying cause
*/
public A2AClientInvalidArgsError(String message, Throwable cause) {
super("Invalid arguments error: " + message, cause);
}
Expand Down
14 changes: 14 additions & 0 deletions spec/src/main/java/io/a2a/spec/A2AClientInvalidStateError.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,27 @@
*/
public class A2AClientInvalidStateError extends A2AClientError {

/**
* Creates a new invalid state error with no message.
*/
public A2AClientInvalidStateError() {
}

/**
* Creates a new invalid state error with the specified message.
*
* @param message the error message
*/
public A2AClientInvalidStateError(String message) {
super("Invalid state error: " + message);
}

/**
* Creates a new invalid state error with the specified message and cause.
*
* @param message the error message
* @param cause the underlying cause
*/
public A2AClientInvalidStateError(String message, Throwable cause) {
super("Invalid state error: " + message, cause);
}
Expand Down
14 changes: 14 additions & 0 deletions spec/src/main/java/io/a2a/spec/A2AClientJSONError.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,27 @@
*/
public class A2AClientJSONError extends A2AClientError {

/**
* Creates a new JSON error with no message.
*/
public A2AClientJSONError() {
}

/**
* Creates a new JSON error with the specified message.
*
* @param message the error message
*/
public A2AClientJSONError(String message) {
super(message);
}

/**
* Creates a new JSON error with the specified message and cause.
*
* @param message the error message
* @param cause the underlying cause
*/
public A2AClientJSONError(String message, Throwable cause) {
super(message, cause);
}
Expand Down
21 changes: 21 additions & 0 deletions spec/src/main/java/io/a2a/spec/A2AErrorCodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,39 @@
*/
public interface A2AErrorCodes {

/** Error code indicating the requested task was not found (-32001). */
int TASK_NOT_FOUND_ERROR_CODE = -32001;

/** Error code indicating the task cannot be canceled in its current state (-32002). */
int TASK_NOT_CANCELABLE_ERROR_CODE = -32002;

/** Error code indicating push notifications are not supported by this agent (-32003). */
int PUSH_NOTIFICATION_NOT_SUPPORTED_ERROR_CODE = -32003;

/** Error code indicating the requested operation is not supported (-32004). */
int UNSUPPORTED_OPERATION_ERROR_CODE = -32004;

/** Error code indicating the content type is not supported (-32005). */
int CONTENT_TYPE_NOT_SUPPORTED_ERROR_CODE = -32005;

/** Error code indicating the agent returned an invalid response (-32006). */
int INVALID_AGENT_RESPONSE_ERROR_CODE = -32006;

/** Error code indicating authenticated extended card is not configured (-32007). */
int AUTHENTICATED_EXTENDED_CARD_NOT_CONFIGURED_ERROR_CODE = -32007;

/** JSON-RPC error code for invalid request structure (-32600). */
int INVALID_REQUEST_ERROR_CODE = -32600;

/** JSON-RPC error code for method not found (-32601). */
int METHOD_NOT_FOUND_ERROR_CODE = -32601;

/** JSON-RPC error code for invalid method parameters (-32602). */
int INVALID_PARAMS_ERROR_CODE = -32602;

/** JSON-RPC error code for internal server errors (-32603). */
int INTERNAL_ERROR_CODE = -32603;

/** JSON-RPC error code for JSON parsing errors (-32700). */
int JSON_PARSE_ERROR_CODE = -32700;
}
19 changes: 19 additions & 0 deletions spec/src/main/java/io/a2a/spec/A2AServerException.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,37 @@
*/
public class A2AServerException extends A2AException {

/**
* Creates a new A2AServerException with no message.
*/
public A2AServerException() {
super();
}

/**
* Creates a new A2AServerException with the specified message.
*
* @param msg the exception message
*/
public A2AServerException(final String msg) {
super(msg);
}

/**
* Creates a new A2AServerException with the specified cause.
*
* @param cause the underlying cause
*/
public A2AServerException(final Throwable cause) {
super(cause);
}

/**
* Creates a new A2AServerException with the specified message and cause.
*
* @param msg the exception message
* @param cause the underlying cause
*/
public A2AServerException(final String msg, final Throwable cause) {
super(msg, cause);
}
Expand Down
91 changes: 91 additions & 0 deletions spec/src/main/java/io/a2a/spec/APIKeySecurityScheme.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
public final class APIKeySecurityScheme implements SecurityScheme {

/** The security scheme type identifier for API key authentication. */
public static final String API_KEY = "apiKey";
private final Location location;
private final String name;
Expand All @@ -28,8 +29,13 @@ public final class APIKeySecurityScheme implements SecurityScheme {
* Represents the location of the API key.
*/
public enum Location {
/** API key sent in a cookie. */
COOKIE("cookie"),

/** API key sent in an HTTP header. */
HEADER("header"),

/** API key sent as a query parameter. */
QUERY("query");

private final String location;
Expand All @@ -38,10 +44,22 @@ public enum Location {
this.location = location;
}

/**
* Converts this location to its string representation.
*
* @return the string representation of this location
*/
public String asString() {
return location;
}

/**
* Converts a string to a Location enum value.
*
* @param location the string location ("cookie", "header", or "query")
* @return the corresponding Location enum value
* @throws IllegalArgumentException if the location string is invalid
*/
public static Location fromString(String location) {
switch (location) {
case "cookie" -> {
Expand All @@ -58,10 +76,27 @@ public static Location fromString(String location) {
}
}

/**
* Creates a new APIKeySecurityScheme with the specified location, name, and description.
*
* @param location the location where the API key is sent (required)
* @param name the name of the API key parameter (required)
* @param description a human-readable description (optional)
* @throws IllegalArgumentException if location or name is null
*/
public APIKeySecurityScheme(Location location, String name, String description) {
this(location, name, description, API_KEY);
}

/**
* Creates a new APIKeySecurityScheme with explicit type specification.
*
* @param location the location where the API key is sent (required)
* @param name the name of the API key parameter (required)
* @param description a human-readable description (optional)
* @param type the security scheme type (must be "apiKey")
* @throws IllegalArgumentException if location, name, or type is null, or if type is not "apiKey"
*/
public APIKeySecurityScheme(Location location, String name,
String description, String type) {
Assert.checkNotNullParam("location", location);
Expand All @@ -76,43 +111,99 @@ public APIKeySecurityScheme(Location location, String name,
this.type = type;
}

/**
* Gets the human-readable description of this security scheme.
*
* @return the description, or null if not provided
*/
@Override
public String getDescription() {
return description;
}

/**
* Gets the location where the API key is sent.
*
* @return the API key location
*/
public Location getLocation() {
return location;
}

/**
* Gets the name of the API key parameter.
*
* @return the parameter name
*/
public String getName() {
return name;
}

/**
* Gets the security scheme type.
*
* @return always returns "apiKey"
*/
public String getType() {
return type;
}

/**
* Builder for constructing immutable {@link APIKeySecurityScheme} instances.
* <p>
* Example usage:
* <pre>{@code
* APIKeySecurityScheme scheme = new APIKeySecurityScheme.Builder()
* .location(Location.HEADER)
* .name("X-API-Key")
* .description("API key authentication")
* .build();
* }</pre>
*/
public static class Builder {
private Location location;
private String name;
private String description;

/**
* Sets the location where the API key should be sent.
*
* @param location the API key location (header, query, or cookie) (required)
* @return this builder for method chaining
*/
public Builder location(Location location) {
this.location = location;
return this;
}

/**
* Sets the name of the API key parameter.
*
* @param name the parameter name (required)
* @return this builder for method chaining
*/
public Builder name(String name) {
this.name = name;
return this;
}

/**
* Sets the human-readable description of the security scheme.
*
* @param description the description (optional)
* @return this builder for method chaining
*/
public Builder description(String description) {
this.description = description;
return this;
}

/**
* Builds a new immutable {@link APIKeySecurityScheme} from the current builder state.
*
* @return a new APIKeySecurityScheme instance
* @throws IllegalArgumentException if location or name is null
*/
public APIKeySecurityScheme build() {
return new APIKeySecurityScheme(location, name, description);
}
Expand Down
6 changes: 6 additions & 0 deletions spec/src/main/java/io/a2a/spec/AgentCapabilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ public static class Builder {
private boolean stateTransitionHistory;
private List<AgentExtension> extensions;

/**
* Creates a new Builder with all capabilities set to false by default.
*/
public Builder() {
}

/**
* Sets whether the agent supports streaming responses.
* <p>
Expand Down
11 changes: 11 additions & 0 deletions spec/src/main/java/io/a2a/spec/AgentCardSignature.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
public record AgentCardSignature(Map<String, Object> header, @SerializedName("protected")String protectedHeader,
String signature) {

/**
* Compact constructor that validates required fields.
*
* @throws IllegalArgumentException if protectedHeader or signature is null
*/
public AgentCardSignature {
Assert.checkNotNullParam("protectedHeader", protectedHeader);
Assert.checkNotNullParam("signature", signature);
Expand All @@ -56,6 +61,12 @@ public static class Builder {
String protectedHeader;
String signature;

/**
* Creates a new Builder with all fields unset.
*/
public Builder() {
}

/**
* Sets the optional unprotected header with additional metadata.
*
Expand Down
Loading