Skip to content
Open
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 @@ -163,13 +163,13 @@ public void shouldSelectCorrectInterfaceWithClientPreference() throws A2AClientE
}

@Test
public void shouldPreserveEmptyTenant() throws A2AClientException {
public void shouldHaveNullTenantWhenNotSet() throws A2AClientException {
ClientBuilder builder = Client
.builder(card)
.withTransport(JSONRPCTransport.class, new JSONRPCTransportConfigBuilder());

AgentInterface selectedInterface = builder.findBestClientTransport();

Assertions.assertEquals("", selectedInterface.tenant());
Assertions.assertNull(selectedInterface.tenant());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@
* Mapper between {@link org.a2aproject.sdk.spec.AgentInterface} and {@link org.a2aproject.sdk.grpc.AgentInterface}.
*/
@Mapper(config = A2AProtoMapperConfig.class,
collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,
uses = A2ACommonFieldMapper.class)
public interface AgentInterfaceMapper {

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

@Mapping(target = "tenant", source = "tenant", conditionExpression = "java(domain.tenant() != null)")
org.a2aproject.sdk.grpc.AgentInterface toProto(org.a2aproject.sdk.spec.AgentInterface domain);

@Mapping(target = "tenant", source = "tenant", qualifiedByName = "emptyToNull")
org.a2aproject.sdk.spec.AgentInterface fromProto(org.a2aproject.sdk.grpc.AgentInterface proto);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* Mapper between {@link org.a2aproject.sdk.grpc.DeleteTaskPushNotificationConfigRequest} and {@link org.a2aproject.sdk.spec.DeleteTaskPushNotificationConfigParams}.
*/
@Mapper(config = A2AProtoMapperConfig.class)
@Mapper(config = A2AProtoMapperConfig.class, uses = A2ACommonFieldMapper.class)
public interface DeleteTaskPushNotificationConfigParamsMapper {

DeleteTaskPushNotificationConfigParamsMapper INSTANCE = A2AMappers.getMapper(DeleteTaskPushNotificationConfigParamsMapper.class);
Expand All @@ -20,14 +20,14 @@ public interface DeleteTaskPushNotificationConfigParamsMapper {
@BeanMapping(builder = @Builder(buildMethod = "build"))
@Mapping(target = "taskId", source = "taskId")
@Mapping(target = "id", source = "id")
@Mapping(target = "tenant", source = "tenant")
@Mapping(target = "tenant", source = "tenant", qualifiedByName = "emptyToNull")
DeleteTaskPushNotificationConfigParams fromProto(org.a2aproject.sdk.grpc.DeleteTaskPushNotificationConfigRequest proto);

/**
* Converts domain DeleteTaskPushNotificationConfigParams to proto DeleteTaskPushNotificationConfigRequest.
*/
@Mapping(target = "taskId", source = "taskId")
@Mapping(target = "id", source = "id")
@Mapping(target = "tenant", source = "tenant")
@Mapping(target = "tenant", source = "tenant", conditionExpression = "java(domain.tenant() != null)")
org.a2aproject.sdk.grpc.DeleteTaskPushNotificationConfigRequest toProto(DeleteTaskPushNotificationConfigParams domain);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* Mapper between {@link org.a2aproject.sdk.grpc.GetTaskPushNotificationConfigRequest} and {@link org.a2aproject.sdk.spec.GetTaskPushNotificationConfigParams}.
*/
@Mapper(config = A2AProtoMapperConfig.class)
@Mapper(config = A2AProtoMapperConfig.class, uses = A2ACommonFieldMapper.class)
public interface GetTaskPushNotificationConfigParamsMapper {

GetTaskPushNotificationConfigParamsMapper INSTANCE = A2AMappers.getMapper(GetTaskPushNotificationConfigParamsMapper.class);
Expand All @@ -20,14 +20,14 @@ public interface GetTaskPushNotificationConfigParamsMapper {
@BeanMapping(builder = @Builder(buildMethod = "build"))
@Mapping(target = "taskId", source = "taskId")
@Mapping(target = "id", source = "id")
@Mapping(target = "tenant", source = "tenant")
@Mapping(target = "tenant", source = "tenant", qualifiedByName = "emptyToNull")
GetTaskPushNotificationConfigParams fromProto(org.a2aproject.sdk.grpc.GetTaskPushNotificationConfigRequest proto);

/**
* Converts domain GetTaskPushNotificationConfigParams to proto GetTaskPushNotificationConfigRequest.
*/
@Mapping(target = "taskId", source = "taskId")
@Mapping(target = "id", source = "id", conditionExpression = "java(domain.id() != null)")
@Mapping(target = "tenant", source = "tenant")
@Mapping(target = "tenant", source = "tenant", conditionExpression = "java(domain.tenant() != null)")
org.a2aproject.sdk.grpc.GetTaskPushNotificationConfigRequest toProto(GetTaskPushNotificationConfigParams domain);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* Mapper between {@link org.a2aproject.sdk.grpc.ListTaskPushNotificationConfigsRequest} and {@link org.a2aproject.sdk.spec.ListTaskPushNotificationConfigsParams}.
*/
@Mapper(config = A2AProtoMapperConfig.class)
@Mapper(config = A2AProtoMapperConfig.class, uses = A2ACommonFieldMapper.class)
public interface ListTaskPushNotificationConfigsParamsMapper {

ListTaskPushNotificationConfigsParamsMapper INSTANCE = A2AMappers.getMapper(ListTaskPushNotificationConfigsParamsMapper.class);
Expand All @@ -19,13 +19,13 @@ public interface ListTaskPushNotificationConfigsParamsMapper {
*/
@BeanMapping(builder = @Builder(buildMethod = "build"))
@Mapping(target = "id", source = "taskId")
@Mapping(target = "tenant", source = "tenant")
@Mapping(target = "tenant", source = "tenant", qualifiedByName = "emptyToNull")
ListTaskPushNotificationConfigsParams fromProto(org.a2aproject.sdk.grpc.ListTaskPushNotificationConfigsRequest proto);

/**
* Converts domain ListTaskPushNotificationConfigsParams to proto ListTaskPushNotificationConfigsRequest.
*/
@Mapping(target = "taskId", source = "id")
@Mapping(target = "tenant", source = "tenant")
@Mapping(target = "tenant", source = "tenant", conditionExpression = "java(domain.tenant() != null)")
org.a2aproject.sdk.grpc.ListTaskPushNotificationConfigsRequest toProto(ListTaskPushNotificationConfigsParams domain);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public interface MessageSendParamsMapper {
*/
@Mapping(target = "configuration", source = "configuration", conditionExpression = "java(domain.configuration() != null)")
@Mapping(target = "metadata", source = "metadata", qualifiedByName = "metadataToProto")
@Mapping(target = "tenant", source = "tenant", conditionExpression = "java(domain.tenant() != null)")
org.a2aproject.sdk.grpc.SendMessageRequest toProto(MessageSendParams domain);

/**
Expand All @@ -31,5 +32,6 @@ public interface MessageSendParamsMapper {
*/
@BeanMapping(builder = @Builder(buildMethod = "build"))
@Mapping(target = "metadata", source = "metadata", qualifiedByName = "metadataFromProto")
@Mapping(target = "tenant", source = "tenant", qualifiedByName = "emptyToNull")
MessageSendParams fromProto(org.a2aproject.sdk.grpc.SendMessageRequest proto);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public interface TaskIdParamsMapper {
@BeanMapping(builder = @Builder(buildMethod = "build"))
@Mapping(target = "id", source = "id")
@Mapping(target = "metadata", source = "metadata", qualifiedByName = "metadataFromProto")
@Mapping(target = "tenant", source = "tenant", qualifiedByName = "emptyToNull")
CancelTaskParams fromProtoCancelTaskRequest(org.a2aproject.sdk.grpc.CancelTaskRequest proto);

/**
Expand All @@ -33,6 +34,7 @@ public interface TaskIdParamsMapper {
@BeanMapping(builder = @Builder(buildMethod = "build"))
@Mapping(target = "id", source = "id")
@Mapping(target = "metadata", source = "metadata", qualifiedByName = "metadataToProto")
@Mapping(target = "tenant", source = "tenant", conditionExpression = "java(domain.tenant() != null)")
org.a2aproject.sdk.grpc.CancelTaskRequest toProtoCancelTaskRequest(CancelTaskParams domain);


Expand All @@ -42,7 +44,7 @@ public interface TaskIdParamsMapper {
*/
@BeanMapping(builder = @Builder(buildMethod = "build"))
@Mapping(target = "id", source = "id")
@Mapping(target = "tenant", source = "tenant")
@Mapping(target = "tenant", source = "tenant", qualifiedByName = "emptyToNull")
TaskIdParams fromProtoSubscribeToTaskRequest(org.a2aproject.sdk.grpc.SubscribeToTaskRequest proto);

/**
Expand All @@ -51,5 +53,6 @@ public interface TaskIdParamsMapper {
*/
@BeanMapping(builder = @Builder(buildMethod = "build"))
@Mapping(target = "id", source = "id")
@Mapping(target = "tenant", source = "tenant", conditionExpression = "java(domain.tenant() != null)")
org.a2aproject.sdk.grpc.SubscribeToTaskRequest toProtoSubscribeToTaskRequest(TaskIdParams domain);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* <p>
* Extracts task ID from resource name format "tasks/{id}" using {@link ResourceNameParser}.
*/
@Mapper(config = A2AProtoMapperConfig.class)
@Mapper(config = A2AProtoMapperConfig.class, uses = A2ACommonFieldMapper.class)
public interface TaskQueryParamsMapper {

TaskQueryParamsMapper INSTANCE = A2AMappers.getMapper(TaskQueryParamsMapper.class);
Expand All @@ -28,6 +28,6 @@ public interface TaskQueryParamsMapper {
@BeanMapping(builder = @Builder(buildMethod = "build"))
@Mapping(target = "id", source = "id")
@Mapping(target = "historyLength", source = "historyLength")
@Mapping(target = "tenant", source = "tenant")
@Mapping(target = "tenant", source = "tenant", conditionExpression = "java(domain.tenant() != null)")
org.a2aproject.sdk.grpc.GetTaskRequest toProto(TaskQueryParams domain);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.a2aproject.sdk.spec;

import org.a2aproject.sdk.util.Assert;
import org.jspecify.annotations.Nullable;

/**
* Declares a combination of a target URL and protocol binding for accessing an agent.
Expand All @@ -19,13 +20,13 @@
* @param protocolBinding the protocol binding supported at this URL (e.g., "JSONRPC", "GRPC", "HTTP+JSON") (required)
* @param url the endpoint URL where this interface is available; must be a valid absolute HTTPS URL in production
* (required)
* @param tenant the tenant to be set in the request when calling the agent.
* @param tenant optional tenant to be set in the request when calling the agent.
* @param protocolVersion the version of the A2A protocol this interface exposes (e.g., "1.0", "0.3") (required)
* @see AgentCard
* @see TransportProtocol
* @see <a href="https://a2a-protocol.org/latest/">A2A Protocol Specification</a>
*/
public record AgentInterface(String protocolBinding, String url, String tenant, String protocolVersion) {
public record AgentInterface(String protocolBinding, String url, @Nullable String tenant, String protocolVersion) {

/** The default A2A Protocol version used when not explicitly specified. */
public static final String CURRENT_PROTOCOL_VERSION = "1.0";
Expand All @@ -42,7 +43,6 @@ public record AgentInterface(String protocolBinding, String url, String tenant,
public AgentInterface {
Assert.checkNotNullParam("protocolBinding", protocolBinding);
Assert.checkNotNullParam("url", url);
Assert.checkNotNullParam("tenant", tenant);

if (protocolVersion == null || protocolVersion.isEmpty()) {
protocolVersion = CURRENT_PROTOCOL_VERSION;
Expand All @@ -67,6 +67,6 @@ public AgentInterface(String protocolBinding, String url, String tenant) {
* @param url the endpoint URL (see class-level JavaDoc)
*/
public AgentInterface(String protocolBinding, String url) {
this(protocolBinding, url, "", CURRENT_PROTOCOL_VERSION);
this(protocolBinding, url, null, CURRENT_PROTOCOL_VERSION);
}
}
10 changes: 4 additions & 6 deletions spec/src/main/java/org/a2aproject/sdk/spec/CancelTaskParams.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.a2aproject.sdk.spec;

import org.a2aproject.sdk.util.Assert;
import org.a2aproject.sdk.util.Utils;
import java.util.Collections;
import java.util.Map;
import org.jspecify.annotations.Nullable;
Expand All @@ -17,7 +16,7 @@
* @param metadata optional arbitrary key-value metadata (e.g. cancellation reason)
* @see <a href="https://a2a-protocol.org/latest/">A2A Protocol Specification</a>
*/
public record CancelTaskParams(String id, String tenant, Map<String, Object> metadata) {
public record CancelTaskParams(String id, @Nullable String tenant, Map<String, Object> metadata) {

/**
* Compact constructor for validation.
Expand All @@ -28,7 +27,6 @@ public record CancelTaskParams(String id, String tenant, Map<String, Object> met
*/
public CancelTaskParams {
Assert.checkNotNullParam("id", id);
Assert.checkNotNullParam("tenant", tenant);
}

/**
Expand All @@ -37,7 +35,7 @@ public record CancelTaskParams(String id, String tenant, Map<String, Object> met
* @param id the task identifier (required)
*/
public CancelTaskParams(String id) {
this(id, "", Collections.emptyMap());
this(id, null, Collections.emptyMap());
}

/**
Expand Down Expand Up @@ -80,7 +78,7 @@ public Builder id(String id) {
* @param tenant the tenant identifier
* @return this builder for method chaining
*/
public Builder tenant(String tenant) {
public Builder tenant(@Nullable String tenant) {
this.tenant = tenant;
return this;
}
Expand All @@ -105,7 +103,7 @@ public Builder metadata(Map<String, Object> metadata) {
public CancelTaskParams build() {
return new CancelTaskParams(
Assert.checkNotNullParam("id", id),
Utils.defaultIfNull(tenant,""),
tenant,
metadata
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@


import org.a2aproject.sdk.util.Assert;
import org.a2aproject.sdk.util.Utils;
import org.jspecify.annotations.Nullable;

/**
Expand All @@ -17,7 +16,7 @@
* @param tenant optional tenant, provided as a path parameter.
* @see <a href="https://a2a-protocol.org/latest/">A2A Protocol Specification</a>
*/
public record DeleteTaskPushNotificationConfigParams(String taskId, String id, String tenant) {
public record DeleteTaskPushNotificationConfigParams(String taskId, String id, @Nullable String tenant) {

/**
* Compact constructor that validates required fields.
Expand All @@ -30,7 +29,6 @@ public record DeleteTaskPushNotificationConfigParams(String taskId, String id, S
public DeleteTaskPushNotificationConfigParams {
Assert.checkNotNullParam("taskId", taskId);
Assert.checkNotNullParam("id", id);
Assert.checkNotNullParam("tenant", tenant);
}

/**
Expand All @@ -41,7 +39,7 @@ public record DeleteTaskPushNotificationConfigParams(String taskId, String id, S
* @throws IllegalArgumentException if taskId or id is null
*/
public DeleteTaskPushNotificationConfigParams(String taskId, String id) {
this(taskId, id, "");
this(taskId, id, null);
}

/**
Expand Down Expand Up @@ -97,7 +95,7 @@ public Builder id(String id) {
* @param tenant arbitrary tenant (optional)
* @return this builder for method chaining
*/
public Builder tenant(String tenant) {
public Builder tenant(@Nullable String tenant) {
this.tenant = tenant;
return this;
}
Expand All @@ -112,7 +110,7 @@ public DeleteTaskPushNotificationConfigParams build() {
return new DeleteTaskPushNotificationConfigParams(
Assert.checkNotNullParam("taskId", taskId),
Assert.checkNotNullParam("id", id),
Utils.defaultIfNull(tenant,""));
tenant);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@


import org.a2aproject.sdk.util.Assert;
import org.a2aproject.sdk.util.Utils;
import org.jspecify.annotations.Nullable;

/**
Expand All @@ -18,7 +17,7 @@
* @see TaskPushNotificationConfig for the returned configuration structure
* @see <a href="https://a2a-protocol.org/latest/">A2A Protocol Specification</a>
*/
public record GetTaskPushNotificationConfigParams(String taskId, String id, String tenant) {
public record GetTaskPushNotificationConfigParams(String taskId, String id, @Nullable String tenant) {

/**
* Compact constructor that validates required fields.
Expand All @@ -31,7 +30,6 @@ public record GetTaskPushNotificationConfigParams(String taskId, String id, Stri
public GetTaskPushNotificationConfigParams {
Assert.checkNotNullParam("taskId", taskId);
Assert.checkNotNullParam("id", id);
Assert.checkNotNullParam("tenant", tenant);
}

/**
Expand All @@ -41,7 +39,7 @@ public record GetTaskPushNotificationConfigParams(String taskId, String id, Stri
* @param id optional configuration ID to retrieve
*/
public GetTaskPushNotificationConfigParams(String taskId, String id) {
this(taskId, id, "");
this(taskId, id, null);
}

/**
Expand Down Expand Up @@ -95,7 +93,7 @@ public Builder id(String id) {
* @param tenant the tenant
* @return this builder for method chaining
*/
public Builder tenant(String tenant) {
public Builder tenant(@Nullable String tenant) {
this.tenant = tenant;
return this;
}
Expand All @@ -109,7 +107,7 @@ public GetTaskPushNotificationConfigParams build() {
return new GetTaskPushNotificationConfigParams(
Assert.checkNotNullParam("taskId", taskId),
Assert.checkNotNullParam("id", id),
Utils.defaultIfNull(tenant,""));
tenant);
}
}
}
Loading
Loading