diff --git a/client/transport/jsonrpc/src/test/java/org/a2aproject/sdk/client/transport/jsonrpc/JSONRPCTransportTest.java b/client/transport/jsonrpc/src/test/java/org/a2aproject/sdk/client/transport/jsonrpc/JSONRPCTransportTest.java index 5349c4753..855c49611 100644 --- a/client/transport/jsonrpc/src/test/java/org/a2aproject/sdk/client/transport/jsonrpc/JSONRPCTransportTest.java +++ b/client/transport/jsonrpc/src/test/java/org/a2aproject/sdk/client/transport/jsonrpc/JSONRPCTransportTest.java @@ -97,14 +97,14 @@ public void tearDown() { public void testListTasksWithDefaultBuilder() throws Exception { JsonObject params = listTasksAndGetRequestParams(ListTasksParams.builder().build()); - assertEquals("", params.get("tenant").getAsString()); + assertFalse(params.has("tenant")); } @Test public void testListTasksWithDefaultConstructor() throws Exception { JsonObject params = listTasksAndGetRequestParams(new ListTasksParams()); - assertEquals("", params.get("tenant").getAsString()); + assertFalse(params.has("tenant")); } @Test diff --git a/client/transport/jsonrpc/src/test/java/org/a2aproject/sdk/client/transport/jsonrpc/JsonMessages.java b/client/transport/jsonrpc/src/test/java/org/a2aproject/sdk/client/transport/jsonrpc/JsonMessages.java index f73e9d8ed..aba7703d7 100644 --- a/client/transport/jsonrpc/src/test/java/org/a2aproject/sdk/client/transport/jsonrpc/JsonMessages.java +++ b/client/transport/jsonrpc/src/test/java/org/a2aproject/sdk/client/transport/jsonrpc/JsonMessages.java @@ -150,8 +150,7 @@ public class JsonMessages { "configuration":{ "acceptedOutputModes":[ "text" - ], - "returnImmediately":false + ] }, "metadata":{ @@ -200,8 +199,7 @@ public class JsonMessages { "configuration":{ "acceptedOutputModes":[ "text" - ], - "returnImmediately":false + ] }, "metadata":{ @@ -384,8 +382,7 @@ public class JsonMessages { "configuration":{ "acceptedOutputModes":[ "text" - ], - "returnImmediately":false + ] }, "metadata":{ @@ -451,8 +448,7 @@ public class JsonMessages { "configuration":{ "acceptedOutputModes":[ "text" - ], - "returnImmediately":false + ] }, "metadata":{ @@ -522,8 +518,7 @@ public class JsonMessages { "configuration":{ "acceptedOutputModes":[ "text" - ], - "returnImmediately":false + ] }, "metadata":{ diff --git a/spec-grpc/src/main/java/org/a2aproject/sdk/grpc/utils/JSONRPCUtils.java b/spec-grpc/src/main/java/org/a2aproject/sdk/grpc/utils/JSONRPCUtils.java index 89cb05c9b..0e9e7bf8b 100644 --- a/spec-grpc/src/main/java/org/a2aproject/sdk/grpc/utils/JSONRPCUtils.java +++ b/spec-grpc/src/main/java/org/a2aproject/sdk/grpc/utils/JSONRPCUtils.java @@ -581,8 +581,9 @@ public static String toJsonRPCRequest(@Nullable String requestId, String method, output.name("method").value(method); } if (payload != null) { + // Unlike responses, omit unset fields: receivers may treat "taskId": "" as a real value String resultValue = ProtoJsonUtils.toJson( - JsonFormat.printer().alwaysPrintFieldsWithNoPresence().omittingInsignificantWhitespace(), payload); + JsonFormat.printer().omittingInsignificantWhitespace(), payload); output.name("params").jsonValue(resultValue); } output.endObject(); diff --git a/spec-grpc/src/test/java/org/a2aproject/sdk/grpc/utils/JSONRPCUtilsTest.java b/spec-grpc/src/test/java/org/a2aproject/sdk/grpc/utils/JSONRPCUtilsTest.java index fcead19af..c7f166588 100644 --- a/spec-grpc/src/test/java/org/a2aproject/sdk/grpc/utils/JSONRPCUtilsTest.java +++ b/spec-grpc/src/test/java/org/a2aproject/sdk/grpc/utils/JSONRPCUtilsTest.java @@ -762,6 +762,32 @@ public void testToJsonRPCRequest_doesNotHtmlEscapeAngleBrackets() { "JSON must not contain HTML-escaped '>' (\\u003e) but got: " + json); } + @Test + public void testToJsonRPCRequest_omitsUnsetFields() throws JsonProcessingException { + // Issue #770: unset taskId, contextId and tenant were sent as empty strings + MessageSendParams params = new MessageSendParams( + Message.builder() + .role(Message.Role.ROLE_USER) + .parts(Collections.singletonList(new TextPart("hello"))) + .messageId("message-1234") + .build(), + null, null + ); + + String json = JSONRPCUtils.toJsonRPCRequest("test-id", SEND_MESSAGE_METHOD, + ProtoUtils.ToProto.sendMessageRequest(params)); + + JsonObject requestParams = JsonParser.parseString(json).getAsJsonObject().getAsJsonObject("params"); + assertFalse(requestParams.has("tenant"), json); + JsonObject message = requestParams.getAsJsonObject("message"); + assertFalse(message.has("taskId"), json); + assertFalse(message.has("contextId"), json); + Message parsed = assertInstanceOf(SendMessageRequest.class, JSONRPCUtils.parseRequestBody(json, null)) + .getParams().message(); + assertNull(parsed.taskId()); + assertNull(parsed.contextId()); + } + @Test public void testToJsonRPCResultResponse_doesNotHtmlEscapeAngleBrackets() { // Reproduce issue #892: server responses must also send literal angle brackets.