diff --git a/.github/workflows/run-tck.yml b/.github/workflows/run-tck.yml index 7793157dc..ed5829956 100644 --- a/.github/workflows/run-tck.yml +++ b/.github/workflows/run-tck.yml @@ -12,7 +12,7 @@ on: env: # Tag of the TCK - TCK_VERSION: v0.2.5 + TCK_VERSION: 0.3.0.alpha # Tells uv to not need a venv, and instead use system UV_SYSTEM_PYTHON: 1 @@ -57,7 +57,7 @@ jobs: working-directory: tck - name: Wait for SUT to start run: | - URL="http://localhost:9999/.well-known/agent.json" + URL="http://localhost:9999/.well-known/agent-card.json" EXPECTED_STATUS=200 TIMEOUT=120 RETRY_INTERVAL=2 diff --git a/client/pom.xml b/client/pom.xml index 0a71440b4..fa381e65e 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -7,7 +7,7 @@ io.github.a2asdk a2a-java-sdk-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT a2a-java-sdk-client diff --git a/client/src/main/java/io/a2a/A2A.java b/client/src/main/java/io/a2a/A2A.java index c8dca80e4..1d1f6260e 100644 --- a/client/src/main/java/io/a2a/A2A.java +++ b/client/src/main/java/io/a2a/A2A.java @@ -101,7 +101,7 @@ public static AgentCard getAgentCard(A2AHttpClient httpClient, String agentUrl) * * @param agentUrl the base URL for the agent whose agent card we want to retrieve * @param relativeCardPath optional path to the agent card endpoint relative to the base - * agent URL, defaults to ".well-known/agent.json" + * agent URL, defaults to ".well-known/agent-card.json" * @param authHeaders the HTTP authentication headers to use * @return the agent card * @throws A2AClientError If an HTTP error occurs fetching the card @@ -117,7 +117,7 @@ public static AgentCard getAgentCard(String agentUrl, String relativeCardPath, M * @param httpClient the http client to use * @param agentUrl the base URL for the agent whose agent card we want to retrieve * @param relativeCardPath optional path to the agent card endpoint relative to the base - * agent URL, defaults to ".well-known/agent.json" + * agent URL, defaults to ".well-known/agent-card.json" * @param authHeaders the HTTP authentication headers to use * @return the agent card * @throws A2AClientError If an HTTP error occurs fetching the card diff --git a/client/src/main/java/io/a2a/client/A2ACardResolver.java b/client/src/main/java/io/a2a/client/A2ACardResolver.java index 88d1e351f..8ec181647 100644 --- a/client/src/main/java/io/a2a/client/A2ACardResolver.java +++ b/client/src/main/java/io/a2a/client/A2ACardResolver.java @@ -20,7 +20,7 @@ public class A2ACardResolver { private final String url; private final Map authHeaders; - private static final String DEFAULT_AGENT_CARD_PATH = "/.well-known/agent.json"; + private static final String DEFAULT_AGENT_CARD_PATH = "/.well-known/agent-card.json"; private static final TypeReference AGENT_CARD_TYPE_REFERENCE = new TypeReference<>() {}; @@ -37,7 +37,7 @@ public A2ACardResolver(A2AHttpClient httpClient, String baseUrl) throws A2AClien * @param httpClient the http client to use * @param baseUrl the base URL for the agent whose agent card we want to retrieve * @param agentCardPath optional path to the agent card endpoint relative to the base - * agent URL, defaults to ".well-known/agent.json" + * agent URL, defaults to ".well-known/agent-card.json" * @throws A2AClientError if the URL for the agent is invalid */ public A2ACardResolver(A2AHttpClient httpClient, String baseUrl, String agentCardPath) throws A2AClientError { @@ -48,7 +48,7 @@ public A2ACardResolver(A2AHttpClient httpClient, String baseUrl, String agentCar * @param httpClient the http client to use * @param baseUrl the base URL for the agent whose agent card we want to retrieve * @param agentCardPath optional path to the agent card endpoint relative to the base - * agent URL, defaults to ".well-known/agent.json" + * agent URL, defaults to ".well-known/agent-card.json" * @param authHeaders the HTTP authentication headers to use. May be {@code null} * @throws A2AClientError if the URL for the agent is invalid */ diff --git a/client/src/main/java/io/a2a/client/A2AClient.java b/client/src/main/java/io/a2a/client/A2AClient.java index 80f8c401c..146e1bc58 100644 --- a/client/src/main/java/io/a2a/client/A2AClient.java +++ b/client/src/main/java/io/a2a/client/A2AClient.java @@ -24,6 +24,8 @@ import io.a2a.spec.DeleteTaskPushNotificationConfigParams; import io.a2a.spec.DeleteTaskPushNotificationConfigRequest; import io.a2a.spec.DeleteTaskPushNotificationConfigResponse; +import io.a2a.spec.GetAuthenticatedExtendedCardRequest; +import io.a2a.spec.GetAuthenticatedExtendedCardResponse; import io.a2a.spec.GetTaskPushNotificationConfigParams; import io.a2a.spec.GetTaskPushNotificationConfigRequest; import io.a2a.spec.GetTaskPushNotificationConfigResponse; @@ -61,6 +63,7 @@ public class A2AClient { private static final TypeReference SET_TASK_PUSH_NOTIFICATION_CONFIG_RESPONSE_REFERENCE = new TypeReference<>() {}; private static final TypeReference LIST_TASK_PUSH_NOTIFICATION_CONFIG_RESPONSE_REFERENCE = new TypeReference<>() {}; private static final TypeReference DELETE_TASK_PUSH_NOTIFICATION_CONFIG_RESPONSE_REFERENCE = new TypeReference<>() {}; + private static final TypeReference GET_AUTHENTICATED_EXTENDED_CARD_RESPONSE_REFERENCE = new TypeReference<>() {}; private final A2AHttpClient httpClient; private final String agentUrl; private AgentCard agentCard; @@ -632,8 +635,51 @@ public void resubscribeToTask(String requestId, TaskIdParams taskIdParams, Consu } } + /** + * Retrieve the authenticated extended agent card. + * + * @param authHeaders the HTTP authentication headers to use + * @return the response + * @throws A2AServerException if retrieving the authenticated extended agent card fails for any reason + */ + public GetAuthenticatedExtendedCardResponse getAuthenticatedExtendedCard(Map authHeaders) throws A2AServerException { + return getAuthenticatedExtendedCard(null, authHeaders); + } + + /** + * Retrieve the authenticated extended agent card. + * + * @param requestId the request ID to use + * @param authHeaders the HTTP authentication headers to use + * @return the response + * @throws A2AServerException if retrieving the authenticated extended agent card fails for any reason + */ + public GetAuthenticatedExtendedCardResponse getAuthenticatedExtendedCard(String requestId, + Map authHeaders) throws A2AServerException { + GetAuthenticatedExtendedCardRequest.Builder requestBuilder = new GetAuthenticatedExtendedCardRequest.Builder() + .jsonrpc(JSONRPCMessage.JSONRPC_VERSION) + .method(GetAuthenticatedExtendedCardRequest.METHOD); + + if (requestId != null) { + requestBuilder.id(requestId); + } + + GetAuthenticatedExtendedCardRequest request = requestBuilder.build(); + + try { + String httpResponseBody = sendPostRequest(request, authHeaders); + return unmarshalResponse(httpResponseBody, GET_AUTHENTICATED_EXTENDED_CARD_RESPONSE_REFERENCE); + } catch (IOException | InterruptedException e) { + throw new A2AServerException("Failed to get authenticated extended agent card: " + e, e); + } + } + private String sendPostRequest(Object value) throws IOException, InterruptedException { - A2AHttpClient.PostBuilder builder = createPostBuilder(value); + return sendPostRequest(value, null); + } + + private String sendPostRequest(Object value, Map authHeaders) throws IOException, InterruptedException { + A2AHttpClient.PostBuilder builder = createPostBuilder(value, authHeaders); A2AHttpResponse response = builder.post(); if (!response.success()) { throw new IOException("Request failed " + response.status()); @@ -642,11 +688,20 @@ private String sendPostRequest(Object value) throws IOException, InterruptedExce } private A2AHttpClient.PostBuilder createPostBuilder(Object value) throws JsonProcessingException { - return httpClient.createPost() + return createPostBuilder(value, null); + } + + private A2AHttpClient.PostBuilder createPostBuilder(Object value, Map authHeaders) throws JsonProcessingException { + A2AHttpClient.PostBuilder builder = httpClient.createPost() .url(agentUrl) .addHeader("Content-Type", "application/json") .body(Utils.OBJECT_MAPPER.writeValueAsString(value)); - + if (authHeaders != null) { + for (Map.Entry entry : authHeaders.entrySet()) { + builder.addHeader(entry.getKey(), entry.getValue()); + } + } + return builder; } private T unmarshalResponse(String response, TypeReference typeReference) diff --git a/client/src/test/java/io/a2a/client/A2ACardResolverTest.java b/client/src/test/java/io/a2a/client/A2ACardResolverTest.java index 8d9ff0f5b..c9ce509d3 100644 --- a/client/src/test/java/io/a2a/client/A2ACardResolverTest.java +++ b/client/src/test/java/io/a2a/client/A2ACardResolverTest.java @@ -20,7 +20,7 @@ public class A2ACardResolverTest { - private static final String AGENT_CARD_PATH = "/.well-known/agent.json"; + private static final String AGENT_CARD_PATH = "/.well-known/agent-card.json"; private static final TypeReference AGENT_CARD_TYPE_REFERENCE = new TypeReference<>() {}; @Test diff --git a/client/src/test/java/io/a2a/client/A2AClientTest.java b/client/src/test/java/io/a2a/client/A2AClientTest.java index eda03e02a..373aa3d9f 100644 --- a/client/src/test/java/io/a2a/client/A2AClientTest.java +++ b/client/src/test/java/io/a2a/client/A2AClientTest.java @@ -4,6 +4,8 @@ import static io.a2a.client.JsonMessages.AUTHENTICATION_EXTENDED_AGENT_CARD; import static io.a2a.client.JsonMessages.CANCEL_TASK_TEST_REQUEST; import static io.a2a.client.JsonMessages.CANCEL_TASK_TEST_RESPONSE; +import static io.a2a.client.JsonMessages.GET_AUTHENTICATED_EXTENDED_AGENT_CARD_REQUEST; +import static io.a2a.client.JsonMessages.GET_AUTHENTICATED_EXTENDED_AGENT_CARD_RESPONSE; import static io.a2a.client.JsonMessages.GET_TASK_PUSH_NOTIFICATION_CONFIG_TEST_REQUEST; import static io.a2a.client.JsonMessages.GET_TASK_PUSH_NOTIFICATION_CONFIG_TEST_RESPONSE; import static io.a2a.client.JsonMessages.GET_TASK_TEST_REQUEST; @@ -38,6 +40,8 @@ import io.a2a.spec.A2AServerException; import io.a2a.spec.AgentCard; +import io.a2a.spec.AgentCardSignature; +import io.a2a.spec.AgentInterface; import io.a2a.spec.AgentSkill; import io.a2a.spec.Artifact; import io.a2a.spec.CancelTaskResponse; @@ -46,6 +50,7 @@ import io.a2a.spec.FilePart; import io.a2a.spec.FileWithBytes; import io.a2a.spec.FileWithUri; +import io.a2a.spec.GetAuthenticatedExtendedCardResponse; import io.a2a.spec.GetTaskPushNotificationConfigParams; import io.a2a.spec.GetTaskPushNotificationConfigResponse; import io.a2a.spec.GetTaskResponse; @@ -65,6 +70,8 @@ import io.a2a.spec.TaskQueryParams; import io.a2a.spec.TaskState; import io.a2a.spec.TextPart; +import io.a2a.spec.TransportProtocol; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -382,7 +389,7 @@ public void testA2AClientGetAgentCard() throws Exception { this.server.when( request() .withMethod("GET") - .withPath("/.well-known/agent.json") + .withPath("/.well-known/agent-card.json") ) .respond( response() @@ -443,24 +450,36 @@ public void testA2AClientGetAgentCard() throws Exception { assertEquals(outputModes, skills.get(1).outputModes()); assertTrue(agentCard.supportsAuthenticatedExtendedCard()); assertEquals("https://georoute-agent.example.com/icon.png", agentCard.iconUrl()); - assertEquals("0.2.5", agentCard.protocolVersion()); + assertEquals("0.2.9", agentCard.protocolVersion()); + assertEquals("JSONRPC", agentCard.preferredTransport()); + List additionalInterfaces = agentCard.additionalInterfaces(); + assertEquals(3, additionalInterfaces.size()); + AgentInterface jsonrpc = new AgentInterface(TransportProtocol.JSONRPC.asString(), "https://georoute-agent.example.com/a2a/v1"); + AgentInterface grpc = new AgentInterface(TransportProtocol.GRPC.asString(), "https://georoute-agent.example.com/a2a/grpc"); + AgentInterface httpJson = new AgentInterface(TransportProtocol.HTTP_JSON.asString(), "https://georoute-agent.example.com/a2a/json"); + assertEquals(jsonrpc, additionalInterfaces.get(0)); + assertEquals(grpc, additionalInterfaces.get(1)); + assertEquals(httpJson, additionalInterfaces.get(2)); } @Test public void testA2AClientGetAuthenticatedExtendedAgentCard() throws Exception { this.server.when( request() - .withMethod("GET") - .withPath("/agent/authenticatedExtendedCard") + .withMethod("POST") + .withPath("/") + .withBody(JsonBody.json(GET_AUTHENTICATED_EXTENDED_AGENT_CARD_REQUEST, MatchType.STRICT)) + ) .respond( response() .withStatusCode(200) - .withBody(AUTHENTICATION_EXTENDED_AGENT_CARD) + .withBody(GET_AUTHENTICATED_EXTENDED_AGENT_CARD_RESPONSE) ); A2AClient client = new A2AClient("http://localhost:4001"); - AgentCard agentCard = client.getAgentCard("/agent/authenticatedExtendedCard", null); + GetAuthenticatedExtendedCardResponse response = client.getAuthenticatedExtendedCard("1", null); + AgentCard agentCard = response.getResult(); assertEquals("GeoSpatial Route Planner Agent Extended", agentCard.name()); assertEquals("Extended description", agentCard.description()); assertEquals("https://georoute-agent.example.com/a2a/v1", agentCard.url()); @@ -516,7 +535,13 @@ public void testA2AClientGetAuthenticatedExtendedAgentCard() throws Exception { assertEquals(List.of("extended"), skills.get(2).tags()); assertTrue(agentCard.supportsAuthenticatedExtendedCard()); assertEquals("https://georoute-agent.example.com/icon.png", agentCard.iconUrl()); - assertEquals("0.2.5", agentCard.protocolVersion()); + assertEquals("0.2.9", agentCard.protocolVersion()); + List signatures = agentCard.signatures(); + assertEquals(1, signatures.size()); + AgentCardSignature signature = new AgentCardSignature(null, + "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpPU0UiLCJraWQiOiJrZXktMSIsImprdSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vYWdlbnQvandrcy5qc29uIn0", + "QFdkNLNszlGj3z3u0YQGt_T9LixY3qtdQpZmsTdDHDe3fXV9y9-B3m2-XgCpzuhiLt8E0tV6HXoZKHv4GtHgKQ"); + assertEquals(signature, signatures.get(0)); } @Test diff --git a/client/src/test/java/io/a2a/client/JsonMessages.java b/client/src/test/java/io/a2a/client/JsonMessages.java index fecf216d0..d59ee0146 100644 --- a/client/src/test/java/io/a2a/client/JsonMessages.java +++ b/client/src/test/java/io/a2a/client/JsonMessages.java @@ -8,68 +8,80 @@ public class JsonMessages { static final String AGENT_CARD = """ { - "name": "GeoSpatial Route Planner Agent", - "description": "Provides advanced route planning, traffic analysis, and custom map generation services. This agent can calculate optimal routes, estimate travel times considering real-time traffic, and create personalized maps with points of interest.", - "url": "https://georoute-agent.example.com/a2a/v1", - "provider": { - "organization": "Example Geo Services Inc.", - "url": "https://www.examplegeoservices.com" - }, - "iconUrl": "https://georoute-agent.example.com/icon.png", - "version": "1.2.0", - "documentationUrl": "https://docs.examplegeoservices.com/georoute-agent/api", - "capabilities": { - "streaming": true, - "pushNotifications": true, - "stateTransitionHistory": false - }, - "securitySchemes": { - "google": { - "type": "openIdConnect", - "openIdConnectUrl": "https://accounts.google.com/.well-known/openid-configuration" - } - }, - "security": [{ "google": ["openid", "profile", "email"] }], - "defaultInputModes": ["application/json", "text/plain"], - "defaultOutputModes": ["application/json", "image/png"], - "skills": [ - { - "id": "route-optimizer-traffic", - "name": "Traffic-Aware Route Optimizer", - "description": "Calculates the optimal driving route between two or more locations, taking into account real-time traffic conditions, road closures, and user preferences (e.g., avoid tolls, prefer highways).", - "tags": ["maps", "routing", "navigation", "directions", "traffic"], - "examples": [ - "Plan a route from '1600 Amphitheatre Parkway, Mountain View, CA' to 'San Francisco International Airport' avoiding tolls.", - "{\\"origin\\": {\\"lat\\": 37.422, \\"lng\\": -122.084}, \\"destination\\": {\\"lat\\": 37.7749, \\"lng\\": -122.4194}, \\"preferences\\": [\\"avoid_ferries\\"]}" - ], - "inputModes": ["application/json", "text/plain"], - "outputModes": [ - "application/json", - "application/vnd.geo+json", - "text/html" - ] - }, - { - "id": "custom-map-generator", - "name": "Personalized Map Generator", - "description": "Creates custom map images or interactive map views based on user-defined points of interest, routes, and style preferences. Can overlay data layers.", - "tags": ["maps", "customization", "visualization", "cartography"], - "examples": [ - "Generate a map of my upcoming road trip with all planned stops highlighted.", - "Show me a map visualizing all coffee shops within a 1-mile radius of my current location." - ], - "inputModes": ["application/json"], - "outputModes": [ - "image/png", - "image/jpeg", - "application/json", - "text/html" - ] - } - ], - "supportsAuthenticatedExtendedCard": true, - "protocolVersion": "0.2.5" - }"""; + "protocolVersion": "0.2.9", + "name": "GeoSpatial Route Planner Agent", + "description": "Provides advanced route planning, traffic analysis, and custom map generation services. This agent can calculate optimal routes, estimate travel times considering real-time traffic, and create personalized maps with points of interest.", + "url": "https://georoute-agent.example.com/a2a/v1", + "preferredTransport": "JSONRPC", + "additionalInterfaces" : [ + {"url": "https://georoute-agent.example.com/a2a/v1", "transport": "JSONRPC"}, + {"url": "https://georoute-agent.example.com/a2a/grpc", "transport": "GRPC"}, + {"url": "https://georoute-agent.example.com/a2a/json", "transport": "HTTP+JSON"} + ], + "provider": { + "organization": "Example Geo Services Inc.", + "url": "https://www.examplegeoservices.com" + }, + "iconUrl": "https://georoute-agent.example.com/icon.png", + "version": "1.2.0", + "documentationUrl": "https://docs.examplegeoservices.com/georoute-agent/api", + "capabilities": { + "streaming": true, + "pushNotifications": true, + "stateTransitionHistory": false + }, + "securitySchemes": { + "google": { + "type": "openIdConnect", + "openIdConnectUrl": "https://accounts.google.com/.well-known/openid-configuration" + } + }, + "security": [{ "google": ["openid", "profile", "email"] }], + "defaultInputModes": ["application/json", "text/plain"], + "defaultOutputModes": ["application/json", "image/png"], + "skills": [ + { + "id": "route-optimizer-traffic", + "name": "Traffic-Aware Route Optimizer", + "description": "Calculates the optimal driving route between two or more locations, taking into account real-time traffic conditions, road closures, and user preferences (e.g., avoid tolls, prefer highways).", + "tags": ["maps", "routing", "navigation", "directions", "traffic"], + "examples": [ + "Plan a route from '1600 Amphitheatre Parkway, Mountain View, CA' to 'San Francisco International Airport' avoiding tolls.", + "{\\"origin\\": {\\"lat\\": 37.422, \\"lng\\": -122.084}, \\"destination\\": {\\"lat\\": 37.7749, \\"lng\\": -122.4194}, \\"preferences\\": [\\"avoid_ferries\\"]}" + ], + "inputModes": ["application/json", "text/plain"], + "outputModes": [ + "application/json", + "application/vnd.geo+json", + "text/html" + ] + }, + { + "id": "custom-map-generator", + "name": "Personalized Map Generator", + "description": "Creates custom map images or interactive map views based on user-defined points of interest, routes, and style preferences. Can overlay data layers.", + "tags": ["maps", "customization", "visualization", "cartography"], + "examples": [ + "Generate a map of my upcoming road trip with all planned stops highlighted.", + "Show me a map visualizing all coffee shops within a 1-mile radius of my current location." + ], + "inputModes": ["application/json"], + "outputModes": [ + "image/png", + "image/jpeg", + "application/json", + "text/html" + ] + } + ], + "supportsAuthenticatedExtendedCard": true, + "signatures": [ + { + "protected": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpPU0UiLCJraWQiOiJrZXktMSIsImprdSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vYWdlbnQvandrcy5qc29uIn0", + "signature": "QFdkNLNszlGj3z3u0YQGt_T9LixY3qtdQpZmsTdDHDe3fXV9y9-B3m2-XgCpzuhiLt8E0tV6HXoZKHv4GtHgKQ" + } + ] + }"""; static final String AUTHENTICATION_EXTENDED_AGENT_CARD = """ { @@ -139,7 +151,13 @@ public class JsonMessages { } ], "supportsAuthenticatedExtendedCard": true, - "protocolVersion": "0.2.5" + "protocolVersion": "0.2.9", + "signatures": [ + { + "protected": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpPU0UiLCJraWQiOiJrZXktMSIsImprdSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vYWdlbnQvandrcy5qc29uIn0", + "signature": "QFdkNLNszlGj3z3u0YQGt_T9LixY3qtdQpZmsTdDHDe3fXV9y9-B3m2-XgCpzuhiLt8E0tV6HXoZKHv4GtHgKQ" + } + ] }"""; @@ -615,4 +633,21 @@ public class JsonMessages { } }"""; + static final String GET_AUTHENTICATED_EXTENDED_AGENT_CARD_REQUEST = """ + { + "jsonrpc": "2.0", + "id": "1", + "method": "agent/getAuthenticatedExtendedCard" + } + """; + + static final String GET_AUTHENTICATED_EXTENDED_AGENT_CARD_RESPONSE = """ + { + "jsonrpc": "2.0", + "id": "1", + "result": + """ + AUTHENTICATION_EXTENDED_AGENT_CARD + + """ + } + """; } diff --git a/common/pom.xml b/common/pom.xml index e4c01920e..504856d3b 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -7,7 +7,7 @@ io.github.a2asdk a2a-java-sdk-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT a2a-java-sdk-common diff --git a/examples/helloworld/client/pom.xml b/examples/helloworld/client/pom.xml index 8edb46cb6..3aaa5c221 100644 --- a/examples/helloworld/client/pom.xml +++ b/examples/helloworld/client/pom.xml @@ -7,7 +7,7 @@ io.github.a2asdk a2a-java-sdk-examples-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT a2a-java-sdk-examples-client diff --git a/examples/helloworld/client/src/main/java/io/a2a/examples/helloworld/HelloWorldRunner.java b/examples/helloworld/client/src/main/java/io/a2a/examples/helloworld/HelloWorldRunner.java index 144972238..84a489367 100644 --- a/examples/helloworld/client/src/main/java/io/a2a/examples/helloworld/HelloWorldRunner.java +++ b/examples/helloworld/client/src/main/java/io/a2a/examples/helloworld/HelloWorldRunner.java @@ -1,5 +1,5 @@ ///usr/bin/env jbang "$0" "$@" ; exit $? -//DEPS io.github.a2asdk:a2a-java-sdk-client:0.2.6.Beta1-SNAPSHOT +//DEPS io.github.a2asdk:a2a-java-sdk-client:0.3.0.Beta1-SNAPSHOT //SOURCES HelloWorldClient.java /** diff --git a/examples/helloworld/pom.xml b/examples/helloworld/pom.xml index d026edb21..a60b123d9 100644 --- a/examples/helloworld/pom.xml +++ b/examples/helloworld/pom.xml @@ -7,7 +7,7 @@ io.github.a2asdk a2a-java-sdk-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT ../../pom.xml diff --git a/examples/helloworld/server/pom.xml b/examples/helloworld/server/pom.xml index 3a051dbab..2b0b15652 100644 --- a/examples/helloworld/server/pom.xml +++ b/examples/helloworld/server/pom.xml @@ -7,7 +7,7 @@ io.github.a2asdk a2a-java-sdk-examples-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT a2a-java-sdk-examples-server diff --git a/pom.xml b/pom.xml index 0a3bfba88..22e44da39 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.a2asdk a2a-java-sdk-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT pom diff --git a/reference/common/pom.xml b/reference/common/pom.xml index 84f4ff74c..8b2af244f 100644 --- a/reference/common/pom.xml +++ b/reference/common/pom.xml @@ -7,7 +7,7 @@ io.github.a2asdk a2a-java-sdk-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT ../../pom.xml a2a-java-sdk-reference-common diff --git a/reference/grpc/pom.xml b/reference/grpc/pom.xml index 2f2d7edd6..61d44ca8a 100644 --- a/reference/grpc/pom.xml +++ b/reference/grpc/pom.xml @@ -6,7 +6,7 @@ io.github.a2asdk a2a-java-sdk-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT ../../pom.xml diff --git a/reference/grpc/src/main/resources/META-INF/beans.xml b/reference/grpc/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..e69de29bb diff --git a/reference/jsonrpc/pom.xml b/reference/jsonrpc/pom.xml index 3f0116ce2..a4342f96c 100644 --- a/reference/jsonrpc/pom.xml +++ b/reference/jsonrpc/pom.xml @@ -7,7 +7,7 @@ io.github.a2asdk a2a-java-sdk-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT ../../pom.xml a2a-java-sdk-reference-jsonrpc @@ -83,4 +83,4 @@ test - \ No newline at end of file + diff --git a/reference/jsonrpc/src/main/java/io/a2a/server/apps/quarkus/A2AServerRoutes.java b/reference/jsonrpc/src/main/java/io/a2a/server/apps/quarkus/A2AServerRoutes.java index 3ebf22ccd..2cd411409 100644 --- a/reference/jsonrpc/src/main/java/io/a2a/server/apps/quarkus/A2AServerRoutes.java +++ b/reference/jsonrpc/src/main/java/io/a2a/server/apps/quarkus/A2AServerRoutes.java @@ -29,6 +29,7 @@ import io.a2a.spec.AgentCard; import io.a2a.spec.CancelTaskRequest; import io.a2a.spec.DeleteTaskPushNotificationConfigRequest; +import io.a2a.spec.GetAuthenticatedExtendedCardRequest; import io.a2a.spec.GetTaskPushNotificationConfigRequest; import io.a2a.spec.GetTaskRequest; import io.a2a.spec.IdJsonMappingException; @@ -72,10 +73,6 @@ public class A2AServerRoutes { @Inject JSONRPCHandler jsonRpcHandler; - @Inject - @ExtendedAgentCard - Instance extendedAgentCard; - // Hook so testing can wait until the MultiSseSupport is subscribed. // Without this we get intermittent failures private static volatile Runnable streamingMultiSseSupportSubscribedRunnable; @@ -159,40 +156,11 @@ private JSONRPCErrorResponse handleError(JsonProcessingException exception) { * * @return the agent card */ - @Route(path = "/.well-known/agent.json", methods = Route.HttpMethod.GET, produces = APPLICATION_JSON) + @Route(path = "/.well-known/agent-card.json", methods = Route.HttpMethod.GET, produces = APPLICATION_JSON) public AgentCard getAgentCard() { return jsonRpcHandler.getAgentCard(); } - /** - * Handles incoming GET requests to the authenticated extended agent card endpoint. - * Returns the agent card in JSON format. - * - */ - @Route(path = "/agent/authenticatedExtendedCard", methods = Route.HttpMethod.GET, produces = APPLICATION_JSON) - public void getAuthenticatedExtendedAgentCard(RoutingExchange re) { - // TODO need to add authentication for this endpoint - // https://github.com/a2aproject/a2a-java/issues/77 - try { - if (! jsonRpcHandler.getAgentCard().supportsAuthenticatedExtendedCard()) { - JSONErrorResponse errorResponse = new JSONErrorResponse("Extended agent card not supported or not enabled."); - re.response().setStatusCode(Response.Status.NOT_FOUND.getStatusCode()) - .end(Utils.OBJECT_MAPPER.writeValueAsString(errorResponse)); - return; - } - if (! extendedAgentCard.isResolvable()) { - JSONErrorResponse errorResponse = new JSONErrorResponse("Authenticated extended agent card is supported but not configured on the server."); - re.response().setStatusCode(Response.Status.NOT_FOUND.getStatusCode()) - .end(Utils.OBJECT_MAPPER.writeValueAsString(errorResponse)); - return; - } - - re.response().end(Utils.OBJECT_MAPPER.writeValueAsString(extendedAgentCard.get())); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - private JSONRPCResponse processNonStreamingRequest( NonStreamingJSONRPCRequest request, ServerCallContext context) { if (request instanceof GetTaskRequest req) { @@ -209,6 +177,8 @@ private JSONRPCResponse processNonStreamingRequest( return jsonRpcHandler.listPushNotificationConfig(req, context); } else if (request instanceof DeleteTaskPushNotificationConfigRequest req) { return jsonRpcHandler.deletePushNotificationConfig(req, context); + } else if (request instanceof GetAuthenticatedExtendedCardRequest req) { + return jsonRpcHandler.onGetAuthenticatedExtendedCardRequest(req, context); } else { return generateErrorResponse(request, new UnsupportedOperationError()); } diff --git a/server-common/pom.xml b/server-common/pom.xml index caf58b2d1..5677d4d02 100644 --- a/server-common/pom.xml +++ b/server-common/pom.xml @@ -7,7 +7,7 @@ io.github.a2asdk a2a-java-sdk-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT a2a-java-sdk-server-common diff --git a/spec-grpc/pom.xml b/spec-grpc/pom.xml index 879007ace..d72663392 100644 --- a/spec-grpc/pom.xml +++ b/spec-grpc/pom.xml @@ -7,7 +7,7 @@ io.github.a2asdk a2a-java-sdk-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT a2a-java-sdk-spec-grpc diff --git a/spec-grpc/src/main/java/io/a2a/grpc/A2A.java b/spec-grpc/src/main/java/io/a2a/grpc/A2A.java index ae331178e..69060d5aa 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/A2A.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/A2A.java @@ -121,6 +121,11 @@ public static void registerAllExtensions( static final com.google.protobuf.GeneratedMessage.FieldAccessorTable internal_static_a2a_v1_AgentSkill_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_a2a_v1_AgentCardSignature_descriptor; + static final + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_a2a_v1_AgentCardSignature_fieldAccessorTable; static final com.google.protobuf.Descriptors.Descriptor internal_static_a2a_v1_TaskPushNotificationConfig_descriptor; static final @@ -166,6 +171,11 @@ public static void registerAllExtensions( static final com.google.protobuf.GeneratedMessage.FieldAccessorTable internal_static_a2a_v1_OpenIdConnectSecurityScheme_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_a2a_v1_MutualTlsSecurityScheme_descriptor; + static final + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_a2a_v1_MutualTlsSecurityScheme_fieldAccessorTable; static final com.google.protobuf.Descriptors.Descriptor internal_static_a2a_v1_OAuthFlows_descriptor; static final @@ -326,7 +336,7 @@ public static void registerAllExtensions( "AuthenticationInfo\":\n\022AuthenticationInfo" + "\022\017\n\007schemes\030\001 \003(\t\022\023\n\013credentials\030\002 \001(\t\"0" + "\n\016AgentInterface\022\013\n\003url\030\001 \001(\t\022\021\n\ttranspo" + - "rt\030\002 \001(\t\"\362\004\n\tAgentCard\022\030\n\020protocol_versi" + + "rt\030\002 \001(\t\"\242\005\n\tAgentCard\022\030\n\020protocol_versi" + "on\030\020 \001(\t\022\014\n\004name\030\001 \001(\t\022\023\n\013description\030\002 " + "\001(\t\022\013\n\003url\030\003 \001(\t\022\033\n\023preferred_transport\030" + "\016 \001(\t\0225\n\025additional_interfaces\030\017 \003(\0132\026.a" + @@ -339,137 +349,146 @@ public static void registerAllExtensions( ".a2a.v1.Security\022\033\n\023default_input_modes\030" + "\n \003(\t\022\034\n\024default_output_modes\030\013 \003(\t\022\"\n\006s" + "kills\030\014 \003(\0132\022.a2a.v1.AgentSkill\022,\n$suppo" + - "rts_authenticated_extended_card\030\r \001(\010\032N\n" + - "\024SecuritySchemesEntry\022\013\n\003key\030\001 \001(\t\022%\n\005va" + - "lue\030\002 \001(\0132\026.a2a.v1.SecurityScheme:\0028\001\"2\n" + - "\rAgentProvider\022\013\n\003url\030\001 \001(\t\022\024\n\014organizat" + - "ion\030\002 \001(\t\"n\n\021AgentCapabilities\022\021\n\tstream" + - "ing\030\001 \001(\010\022\032\n\022push_notifications\030\002 \001(\010\022*\n" + - "\nextensions\030\003 \003(\0132\026.a2a.v1.AgentExtensio" + - "n\"m\n\016AgentExtension\022\013\n\003uri\030\001 \001(\t\022\023\n\013desc" + - "ription\030\002 \001(\t\022\020\n\010required\030\003 \001(\010\022\'\n\006param" + - "s\030\004 \001(\0132\027.google.protobuf.Struct\"\206\001\n\nAge" + - "ntSkill\022\n\n\002id\030\001 \001(\t\022\014\n\004name\030\002 \001(\t\022\023\n\013des" + - "cription\030\003 \001(\t\022\014\n\004tags\030\004 \003(\t\022\020\n\010examples" + - "\030\005 \003(\t\022\023\n\013input_modes\030\006 \003(\t\022\024\n\014output_mo" + - "des\030\007 \003(\t\"l\n\032TaskPushNotificationConfig\022" + - "\014\n\004name\030\001 \001(\t\022@\n\030push_notification_confi" + - "g\030\002 \001(\0132\036.a2a.v1.PushNotificationConfig\"" + - "\032\n\nStringList\022\014\n\004list\030\001 \003(\t\"~\n\010Security\022" + - ".\n\007schemes\030\001 \003(\0132\035.a2a.v1.Security.Schem" + - "esEntry\032B\n\014SchemesEntry\022\013\n\003key\030\001 \001(\t\022!\n\005" + - "value\030\002 \001(\0132\022.a2a.v1.StringList:\0028\001\"\260\002\n\016" + - "SecurityScheme\022?\n\027api_key_security_schem" + - "e\030\001 \001(\0132\034.a2a.v1.APIKeySecuritySchemeH\000\022" + - "C\n\031http_auth_security_scheme\030\002 \001(\0132\036.a2a" + - ".v1.HTTPAuthSecuritySchemeH\000\022>\n\026oauth2_s" + - "ecurity_scheme\030\003 \001(\0132\034.a2a.v1.OAuth2Secu" + - "ritySchemeH\000\022N\n\037open_id_connect_security" + - "_scheme\030\004 \001(\0132#.a2a.v1.OpenIdConnectSecu" + - "ritySchemeH\000B\010\n\006scheme\"K\n\024APIKeySecurity" + - "Scheme\022\023\n\013description\030\001 \001(\t\022\020\n\010location\030" + - "\002 \001(\t\022\014\n\004name\030\003 \001(\t\"T\n\026HTTPAuthSecurityS" + - "cheme\022\023\n\013description\030\001 \001(\t\022\016\n\006scheme\030\002 \001" + - "(\t\022\025\n\rbearer_format\030\003 \001(\t\"N\n\024OAuth2Secur" + - "ityScheme\022\023\n\013description\030\001 \001(\t\022!\n\005flows\030" + - "\002 \001(\0132\022.a2a.v1.OAuthFlows\"O\n\033OpenIdConne" + - "ctSecurityScheme\022\023\n\013description\030\001 \001(\t\022\033\n" + - "\023open_id_connect_url\030\002 \001(\t\"\366\001\n\nOAuthFlow" + - "s\022@\n\022authorization_code\030\001 \001(\0132\".a2a.v1.A" + - "uthorizationCodeOAuthFlowH\000\022@\n\022client_cr" + - "edentials\030\002 \001(\0132\".a2a.v1.ClientCredentia" + - "lsOAuthFlowH\000\022-\n\010implicit\030\003 \001(\0132\031.a2a.v1" + - ".ImplicitOAuthFlowH\000\022-\n\010password\030\004 \001(\0132\031" + - ".a2a.v1.PasswordOAuthFlowH\000B\006\n\004flow\"\316\001\n\032" + - "AuthorizationCodeOAuthFlow\022\031\n\021authorizat" + - "ion_url\030\001 \001(\t\022\021\n\ttoken_url\030\002 \001(\t\022\023\n\013refr" + - "esh_url\030\003 \001(\t\022>\n\006scopes\030\004 \003(\0132..a2a.v1.A" + - "uthorizationCodeOAuthFlow.ScopesEntry\032-\n" + - "\013ScopesEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t" + - ":\0028\001\"\263\001\n\032ClientCredentialsOAuthFlow\022\021\n\tt" + - "oken_url\030\001 \001(\t\022\023\n\013refresh_url\030\002 \001(\t\022>\n\006s" + - "copes\030\003 \003(\0132..a2a.v1.ClientCredentialsOA" + - "uthFlow.ScopesEntry\032-\n\013ScopesEntry\022\013\n\003ke" + - "y\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"\251\001\n\021ImplicitO" + - "AuthFlow\022\031\n\021authorization_url\030\001 \001(\t\022\023\n\013r" + - "efresh_url\030\002 \001(\t\0225\n\006scopes\030\003 \003(\0132%.a2a.v" + - "1.ImplicitOAuthFlow.ScopesEntry\032-\n\013Scope" + - "sEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"\241" + - "\001\n\021PasswordOAuthFlow\022\021\n\ttoken_url\030\001 \001(\t\022" + - "\023\n\013refresh_url\030\002 \001(\t\0225\n\006scopes\030\003 \003(\0132%.a" + - "2a.v1.PasswordOAuthFlow.ScopesEntry\032-\n\013S" + - "copesEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\002" + - "8\001\"\237\001\n\022SendMessageRequest\022%\n\007request\030\001 \001" + - "(\0132\017.a2a.v1.MessageB\003\340A\002\0227\n\rconfiguratio" + - "n\030\002 \001(\0132 .a2a.v1.SendMessageConfiguratio" + - "n\022)\n\010metadata\030\003 \001(\0132\027.google.protobuf.St" + - "ruct\";\n\016GetTaskRequest\022\021\n\004name\030\001 \001(\tB\003\340A" + - "\002\022\026\n\016history_length\030\002 \001(\005\"!\n\021CancelTaskR" + - "equest\022\014\n\004name\030\001 \001(\t\"4\n$GetTaskPushNotif" + - "icationConfigRequest\022\014\n\004name\030\001 \001(\t\"7\n\'De" + - "leteTaskPushNotificationConfigRequest\022\014\n" + - "\004name\030\001 \001(\t\"\217\001\n\'CreateTaskPushNotificati" + - "onConfigRequest\022\023\n\006parent\030\001 \001(\tB\003\340A\002\022\026\n\t" + - "config_id\030\002 \001(\tB\003\340A\002\0227\n\006config\030\003 \001(\0132\".a" + - "2a.v1.TaskPushNotificationConfigB\003\340A\002\"\'\n" + - "\027TaskSubscriptionRequest\022\014\n\004name\030\001 \001(\t\"^" + - "\n%ListTaskPushNotificationConfigRequest\022" + - "\016\n\006parent\030\001 \001(\t\022\021\n\tpage_size\030\002 \001(\005\022\022\n\npa" + - "ge_token\030\003 \001(\t\"\025\n\023GetAgentCardRequest\"g\n" + - "\023SendMessageResponse\022\034\n\004task\030\001 \001(\0132\014.a2a" + - ".v1.TaskH\000\022\'\n\003msg\030\002 \001(\0132\017.a2a.v1.Message" + - "H\000R\007messageB\t\n\007payload\"\326\001\n\016StreamRespons" + - "e\022\034\n\004task\030\001 \001(\0132\014.a2a.v1.TaskH\000\022\'\n\003msg\030\002" + - " \001(\0132\017.a2a.v1.MessageH\000R\007message\0226\n\rstat" + - "us_update\030\003 \001(\0132\035.a2a.v1.TaskStatusUpdat" + - "eEventH\000\022:\n\017artifact_update\030\004 \001(\0132\037.a2a." + - "v1.TaskArtifactUpdateEventH\000B\t\n\007payload\"" + - "v\n&ListTaskPushNotificationConfigRespons" + - "e\0223\n\007configs\030\001 \003(\0132\".a2a.v1.TaskPushNoti" + - "ficationConfig\022\027\n\017next_page_token\030\002 \001(\t*" + - "\372\001\n\tTaskState\022\032\n\026TASK_STATE_UNSPECIFIED\020" + - "\000\022\030\n\024TASK_STATE_SUBMITTED\020\001\022\026\n\022TASK_STAT" + - "E_WORKING\020\002\022\030\n\024TASK_STATE_COMPLETED\020\003\022\025\n" + - "\021TASK_STATE_FAILED\020\004\022\030\n\024TASK_STATE_CANCE" + - "LLED\020\005\022\035\n\031TASK_STATE_INPUT_REQUIRED\020\006\022\027\n" + - "\023TASK_STATE_REJECTED\020\007\022\034\n\030TASK_STATE_AUT" + - "H_REQUIRED\020\010*;\n\004Role\022\024\n\020ROLE_UNSPECIFIED" + - "\020\000\022\r\n\tROLE_USER\020\001\022\016\n\nROLE_AGENT\020\0022\272\n\n\nA2" + - "AService\022c\n\013SendMessage\022\032.a2a.v1.SendMes" + - "sageRequest\032\033.a2a.v1.SendMessageResponse" + - "\"\033\202\323\344\223\002\025\"\020/v1/message:send:\001*\022k\n\024SendStr" + - "eamingMessage\022\032.a2a.v1.SendMessageReques" + - "t\032\026.a2a.v1.StreamResponse\"\035\202\323\344\223\002\027\"\022/v1/m" + - "essage:stream:\001*0\001\022R\n\007GetTask\022\026.a2a.v1.G" + - "etTaskRequest\032\014.a2a.v1.Task\"!\332A\004name\202\323\344\223" + - "\002\024\022\022/v1/{name=tasks/*}\022[\n\nCancelTask\022\031.a" + - "2a.v1.CancelTaskRequest\032\014.a2a.v1.Task\"$\202" + - "\323\344\223\002\036\"\031/v1/{name=tasks/*}:cancel:\001*\022s\n\020T" + - "askSubscription\022\037.a2a.v1.TaskSubscriptio" + - "nRequest\032\026.a2a.v1.StreamResponse\"$\202\323\344\223\002\036" + - "\022\034/v1/{name=tasks/*}:subscribe0\001\022\304\001\n Cre" + - "ateTaskPushNotificationConfig\022/.a2a.v1.C" + - "reateTaskPushNotificationConfigRequest\032\"" + - ".a2a.v1.TaskPushNotificationConfig\"K\332A\rp" + - "arent,config\202\323\344\223\0025\"+/v1/{parent=task/*/p" + - "ushNotificationConfigs}:\006config\022\256\001\n\035GetT" + - "askPushNotificationConfig\022,.a2a.v1.GetTa" + - "skPushNotificationConfigRequest\032\".a2a.v1" + - ".TaskPushNotificationConfig\";\332A\004name\202\323\344\223" + - "\002.\022,/v1/{name=tasks/*/pushNotificationCo" + - "nfigs/*}\022\276\001\n\036ListTaskPushNotificationCon" + - "fig\022-.a2a.v1.ListTaskPushNotificationCon" + - "figRequest\032..a2a.v1.ListTaskPushNotifica" + - "tionConfigResponse\"=\332A\006parent\202\323\344\223\002.\022,/v1" + - "/{parent=tasks/*}/pushNotificationConfig" + - "s\022P\n\014GetAgentCard\022\033.a2a.v1.GetAgentCardR" + - "equest\032\021.a2a.v1.AgentCard\"\020\202\323\344\223\002\n\022\010/v1/c" + - "ard\022\250\001\n DeleteTaskPushNotificationConfig" + - "\022/.a2a.v1.DeleteTaskPushNotificationConf" + - "igRequest\032\026.google.protobuf.Empty\";\332A\004na" + - "me\202\323\344\223\002.*,/v1/{name=tasks/*/pushNotifica" + - "tionConfigs/*}B7\n\013io.a2a.grpcB\003A2AP\001Z\030go" + - "ogle.golang.org/a2a/v1\252\002\006A2a.V1b\006proto3" + "rts_authenticated_extended_card\030\r \001(\010\022.\n" + + "\nsignatures\030\021 \003(\0132\032.a2a.v1.AgentCardSign" + + "ature\032N\n\024SecuritySchemesEntry\022\013\n\003key\030\001 \001" + + "(\t\022%\n\005value\030\002 \001(\0132\026.a2a.v1.SecuritySchem" + + "e:\0028\001\"2\n\rAgentProvider\022\013\n\003url\030\001 \001(\t\022\024\n\014o" + + "rganization\030\002 \001(\t\"n\n\021AgentCapabilities\022\021" + + "\n\tstreaming\030\001 \001(\010\022\032\n\022push_notifications\030" + + "\002 \001(\010\022*\n\nextensions\030\003 \003(\0132\026.a2a.v1.Agent" + + "Extension\"m\n\016AgentExtension\022\013\n\003uri\030\001 \001(\t" + + "\022\023\n\013description\030\002 \001(\t\022\020\n\010required\030\003 \001(\010\022" + + "\'\n\006params\030\004 \001(\0132\027.google.protobuf.Struct" + + "\"\252\001\n\nAgentSkill\022\n\n\002id\030\001 \001(\t\022\014\n\004name\030\002 \001(" + + "\t\022\023\n\013description\030\003 \001(\t\022\014\n\004tags\030\004 \003(\t\022\020\n\010" + + "examples\030\005 \003(\t\022\023\n\013input_modes\030\006 \003(\t\022\024\n\014o" + + "utput_modes\030\007 \003(\t\022\"\n\010security\030\010 \003(\0132\020.a2" + + "a.v1.Security\"m\n\022AgentCardSignature\022\026\n\tp" + + "rotected\030\001 \001(\tB\003\340A\002\022\026\n\tsignature\030\002 \001(\tB\003" + + "\340A\002\022\'\n\006header\030\003 \001(\0132\027.google.protobuf.St" + + "ruct\"l\n\032TaskPushNotificationConfig\022\014\n\004na" + + "me\030\001 \001(\t\022@\n\030push_notification_config\030\002 \001" + + "(\0132\036.a2a.v1.PushNotificationConfig\"\032\n\nSt" + + "ringList\022\014\n\004list\030\001 \003(\t\"~\n\010Security\022.\n\007sc" + + "hemes\030\001 \003(\0132\035.a2a.v1.Security.SchemesEnt" + + "ry\032B\n\014SchemesEntry\022\013\n\003key\030\001 \001(\t\022!\n\005value" + + "\030\002 \001(\0132\022.a2a.v1.StringList:\0028\001\"\361\002\n\016Secur" + + "ityScheme\022?\n\027api_key_security_scheme\030\001 \001" + + "(\0132\034.a2a.v1.APIKeySecuritySchemeH\000\022C\n\031ht" + + "tp_auth_security_scheme\030\002 \001(\0132\036.a2a.v1.H" + + "TTPAuthSecuritySchemeH\000\022>\n\026oauth2_securi" + + "ty_scheme\030\003 \001(\0132\034.a2a.v1.OAuth2SecurityS" + + "chemeH\000\022N\n\037open_id_connect_security_sche" + + "me\030\004 \001(\0132#.a2a.v1.OpenIdConnectSecurityS" + + "chemeH\000\022?\n\024mtls_security_scheme\030\005 \001(\0132\037." + + "a2a.v1.MutualTlsSecuritySchemeH\000B\010\n\006sche" + + "me\"K\n\024APIKeySecurityScheme\022\023\n\013descriptio" + + "n\030\001 \001(\t\022\020\n\010location\030\002 \001(\t\022\014\n\004name\030\003 \001(\t\"" + + "T\n\026HTTPAuthSecurityScheme\022\023\n\013description" + + "\030\001 \001(\t\022\016\n\006scheme\030\002 \001(\t\022\025\n\rbearer_format\030" + + "\003 \001(\t\"k\n\024OAuth2SecurityScheme\022\023\n\013descrip" + + "tion\030\001 \001(\t\022!\n\005flows\030\002 \001(\0132\022.a2a.v1.OAuth" + + "Flows\022\033\n\023oauth2_metadata_url\030\003 \001(\t\"O\n\033Op" + + "enIdConnectSecurityScheme\022\023\n\013description" + + "\030\001 \001(\t\022\033\n\023open_id_connect_url\030\002 \001(\t\".\n\027M" + + "utualTlsSecurityScheme\022\023\n\013description\030\001 " + + "\001(\t\"\366\001\n\nOAuthFlows\022@\n\022authorization_code" + + "\030\001 \001(\0132\".a2a.v1.AuthorizationCodeOAuthFl" + + "owH\000\022@\n\022client_credentials\030\002 \001(\0132\".a2a.v" + + "1.ClientCredentialsOAuthFlowH\000\022-\n\010implic" + + "it\030\003 \001(\0132\031.a2a.v1.ImplicitOAuthFlowH\000\022-\n" + + "\010password\030\004 \001(\0132\031.a2a.v1.PasswordOAuthFl" + + "owH\000B\006\n\004flow\"\316\001\n\032AuthorizationCodeOAuthF" + + "low\022\031\n\021authorization_url\030\001 \001(\t\022\021\n\ttoken_" + + "url\030\002 \001(\t\022\023\n\013refresh_url\030\003 \001(\t\022>\n\006scopes" + + "\030\004 \003(\0132..a2a.v1.AuthorizationCodeOAuthFl" + + "ow.ScopesEntry\032-\n\013ScopesEntry\022\013\n\003key\030\001 \001" + + "(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"\263\001\n\032ClientCredenti" + + "alsOAuthFlow\022\021\n\ttoken_url\030\001 \001(\t\022\023\n\013refre" + + "sh_url\030\002 \001(\t\022>\n\006scopes\030\003 \003(\0132..a2a.v1.Cl" + + "ientCredentialsOAuthFlow.ScopesEntry\032-\n\013" + + "ScopesEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:" + + "\0028\001\"\251\001\n\021ImplicitOAuthFlow\022\031\n\021authorizati" + + "on_url\030\001 \001(\t\022\023\n\013refresh_url\030\002 \001(\t\0225\n\006sco" + + "pes\030\003 \003(\0132%.a2a.v1.ImplicitOAuthFlow.Sco" + + "pesEntry\032-\n\013ScopesEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005" + + "value\030\002 \001(\t:\0028\001\"\241\001\n\021PasswordOAuthFlow\022\021\n" + + "\ttoken_url\030\001 \001(\t\022\023\n\013refresh_url\030\002 \001(\t\0225\n" + + "\006scopes\030\003 \003(\0132%.a2a.v1.PasswordOAuthFlow" + + ".ScopesEntry\032-\n\013ScopesEntry\022\013\n\003key\030\001 \001(\t" + + "\022\r\n\005value\030\002 \001(\t:\0028\001\"\250\001\n\022SendMessageReque" + + "st\022.\n\007request\030\001 \001(\0132\017.a2a.v1.MessageB\003\340A" + + "\002R\007message\0227\n\rconfiguration\030\002 \001(\0132 .a2a." + + "v1.SendMessageConfiguration\022)\n\010metadata\030" + + "\003 \001(\0132\027.google.protobuf.Struct\";\n\016GetTas" + + "kRequest\022\021\n\004name\030\001 \001(\tB\003\340A\002\022\026\n\016history_l" + + "ength\030\002 \001(\005\"!\n\021CancelTaskRequest\022\014\n\004name" + + "\030\001 \001(\t\"4\n$GetTaskPushNotificationConfigR" + + "equest\022\014\n\004name\030\001 \001(\t\"7\n\'DeleteTaskPushNo" + + "tificationConfigRequest\022\014\n\004name\030\001 \001(\t\"\217\001" + + "\n\'CreateTaskPushNotificationConfigReques" + + "t\022\023\n\006parent\030\001 \001(\tB\003\340A\002\022\026\n\tconfig_id\030\002 \001(" + + "\tB\003\340A\002\0227\n\006config\030\003 \001(\0132\".a2a.v1.TaskPush" + + "NotificationConfigB\003\340A\002\"\'\n\027TaskSubscript" + + "ionRequest\022\014\n\004name\030\001 \001(\t\"^\n%ListTaskPush" + + "NotificationConfigRequest\022\016\n\006parent\030\001 \001(" + + "\t\022\021\n\tpage_size\030\002 \001(\005\022\022\n\npage_token\030\003 \001(\t" + + "\"\025\n\023GetAgentCardRequest\"g\n\023SendMessageRe" + + "sponse\022\034\n\004task\030\001 \001(\0132\014.a2a.v1.TaskH\000\022\'\n\003" + + "msg\030\002 \001(\0132\017.a2a.v1.MessageH\000R\007messageB\t\n" + + "\007payload\"\326\001\n\016StreamResponse\022\034\n\004task\030\001 \001(" + + "\0132\014.a2a.v1.TaskH\000\022\'\n\003msg\030\002 \001(\0132\017.a2a.v1." + + "MessageH\000R\007message\0226\n\rstatus_update\030\003 \001(" + + "\0132\035.a2a.v1.TaskStatusUpdateEventH\000\022:\n\017ar" + + "tifact_update\030\004 \001(\0132\037.a2a.v1.TaskArtifac" + + "tUpdateEventH\000B\t\n\007payload\"v\n&ListTaskPus" + + "hNotificationConfigResponse\0223\n\007configs\030\001" + + " \003(\0132\".a2a.v1.TaskPushNotificationConfig" + + "\022\027\n\017next_page_token\030\002 \001(\t*\372\001\n\tTaskState\022" + + "\032\n\026TASK_STATE_UNSPECIFIED\020\000\022\030\n\024TASK_STAT" + + "E_SUBMITTED\020\001\022\026\n\022TASK_STATE_WORKING\020\002\022\030\n" + + "\024TASK_STATE_COMPLETED\020\003\022\025\n\021TASK_STATE_FA" + + "ILED\020\004\022\030\n\024TASK_STATE_CANCELLED\020\005\022\035\n\031TASK" + + "_STATE_INPUT_REQUIRED\020\006\022\027\n\023TASK_STATE_RE" + + "JECTED\020\007\022\034\n\030TASK_STATE_AUTH_REQUIRED\020\010*;" + + "\n\004Role\022\024\n\020ROLE_UNSPECIFIED\020\000\022\r\n\tROLE_USE" + + "R\020\001\022\016\n\nROLE_AGENT\020\0022\272\n\n\nA2AService\022c\n\013Se" + + "ndMessage\022\032.a2a.v1.SendMessageRequest\032\033." + + "a2a.v1.SendMessageResponse\"\033\202\323\344\223\002\025\"\020/v1/" + + "message:send:\001*\022k\n\024SendStreamingMessage\022" + + "\032.a2a.v1.SendMessageRequest\032\026.a2a.v1.Str" + + "eamResponse\"\035\202\323\344\223\002\027\"\022/v1/message:stream:" + + "\001*0\001\022R\n\007GetTask\022\026.a2a.v1.GetTaskRequest\032" + + "\014.a2a.v1.Task\"!\332A\004name\202\323\344\223\002\024\022\022/v1/{name=" + + "tasks/*}\022[\n\nCancelTask\022\031.a2a.v1.CancelTa" + + "skRequest\032\014.a2a.v1.Task\"$\202\323\344\223\002\036\"\031/v1/{na" + + "me=tasks/*}:cancel:\001*\022s\n\020TaskSubscriptio" + + "n\022\037.a2a.v1.TaskSubscriptionRequest\032\026.a2a" + + ".v1.StreamResponse\"$\202\323\344\223\002\036\022\034/v1/{name=ta" + + "sks/*}:subscribe0\001\022\304\001\n CreateTaskPushNot" + + "ificationConfig\022/.a2a.v1.CreateTaskPushN" + + "otificationConfigRequest\032\".a2a.v1.TaskPu" + + "shNotificationConfig\"K\332A\rparent,config\202\323" + + "\344\223\0025\"+/v1/{parent=task/*/pushNotificatio" + + "nConfigs}:\006config\022\256\001\n\035GetTaskPushNotific" + + "ationConfig\022,.a2a.v1.GetTaskPushNotifica" + + "tionConfigRequest\032\".a2a.v1.TaskPushNotif" + + "icationConfig\";\332A\004name\202\323\344\223\002.\022,/v1/{name=" + + "tasks/*/pushNotificationConfigs/*}\022\276\001\n\036L" + + "istTaskPushNotificationConfig\022-.a2a.v1.L" + + "istTaskPushNotificationConfigRequest\032..a" + + "2a.v1.ListTaskPushNotificationConfigResp" + + "onse\"=\332A\006parent\202\323\344\223\002.\022,/v1/{parent=tasks" + + "/*}/pushNotificationConfigs\022P\n\014GetAgentC" + + "ard\022\033.a2a.v1.GetAgentCardRequest\032\021.a2a.v" + + "1.AgentCard\"\020\202\323\344\223\002\n\022\010/v1/card\022\250\001\n Delete" + + "TaskPushNotificationConfig\022/.a2a.v1.Dele" + + "teTaskPushNotificationConfigRequest\032\026.go" + + "ogle.protobuf.Empty\";\332A\004name\202\323\344\223\002.*,/v1/" + + "{name=tasks/*/pushNotificationConfigs/*}" + + "B7\n\013io.a2a.grpcB\003A2AP\001Z\030google.golang.or" + + "g/a2a/v1\252\002\006A2a.V1b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, @@ -564,7 +583,7 @@ public static void registerAllExtensions( internal_static_a2a_v1_AgentCard_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_AgentCard_descriptor, - new java.lang.String[] { "ProtocolVersion", "Name", "Description", "Url", "PreferredTransport", "AdditionalInterfaces", "Provider", "Version", "DocumentationUrl", "Capabilities", "SecuritySchemes", "Security", "DefaultInputModes", "DefaultOutputModes", "Skills", "SupportsAuthenticatedExtendedCard", }); + new java.lang.String[] { "ProtocolVersion", "Name", "Description", "Url", "PreferredTransport", "AdditionalInterfaces", "Provider", "Version", "DocumentationUrl", "Capabilities", "SecuritySchemes", "Security", "DefaultInputModes", "DefaultOutputModes", "Skills", "SupportsAuthenticatedExtendedCard", "Signatures", }); internal_static_a2a_v1_AgentCard_SecuritySchemesEntry_descriptor = internal_static_a2a_v1_AgentCard_descriptor.getNestedTypes().get(0); internal_static_a2a_v1_AgentCard_SecuritySchemesEntry_fieldAccessorTable = new @@ -594,21 +613,27 @@ public static void registerAllExtensions( internal_static_a2a_v1_AgentSkill_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_AgentSkill_descriptor, - new java.lang.String[] { "Id", "Name", "Description", "Tags", "Examples", "InputModes", "OutputModes", }); - internal_static_a2a_v1_TaskPushNotificationConfig_descriptor = + new java.lang.String[] { "Id", "Name", "Description", "Tags", "Examples", "InputModes", "OutputModes", "Security", }); + internal_static_a2a_v1_AgentCardSignature_descriptor = getDescriptor().getMessageTypes().get(18); + internal_static_a2a_v1_AgentCardSignature_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_a2a_v1_AgentCardSignature_descriptor, + new java.lang.String[] { "Protected", "Signature", "Header", }); + internal_static_a2a_v1_TaskPushNotificationConfig_descriptor = + getDescriptor().getMessageTypes().get(19); internal_static_a2a_v1_TaskPushNotificationConfig_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_TaskPushNotificationConfig_descriptor, new java.lang.String[] { "Name", "PushNotificationConfig", }); internal_static_a2a_v1_StringList_descriptor = - getDescriptor().getMessageTypes().get(19); + getDescriptor().getMessageTypes().get(20); internal_static_a2a_v1_StringList_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_StringList_descriptor, new java.lang.String[] { "List", }); internal_static_a2a_v1_Security_descriptor = - getDescriptor().getMessageTypes().get(20); + getDescriptor().getMessageTypes().get(21); internal_static_a2a_v1_Security_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_Security_descriptor, @@ -620,43 +645,49 @@ public static void registerAllExtensions( internal_static_a2a_v1_Security_SchemesEntry_descriptor, new java.lang.String[] { "Key", "Value", }); internal_static_a2a_v1_SecurityScheme_descriptor = - getDescriptor().getMessageTypes().get(21); + getDescriptor().getMessageTypes().get(22); internal_static_a2a_v1_SecurityScheme_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_SecurityScheme_descriptor, - new java.lang.String[] { "ApiKeySecurityScheme", "HttpAuthSecurityScheme", "Oauth2SecurityScheme", "OpenIdConnectSecurityScheme", "Scheme", }); + new java.lang.String[] { "ApiKeySecurityScheme", "HttpAuthSecurityScheme", "Oauth2SecurityScheme", "OpenIdConnectSecurityScheme", "MtlsSecurityScheme", "Scheme", }); internal_static_a2a_v1_APIKeySecurityScheme_descriptor = - getDescriptor().getMessageTypes().get(22); + getDescriptor().getMessageTypes().get(23); internal_static_a2a_v1_APIKeySecurityScheme_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_APIKeySecurityScheme_descriptor, new java.lang.String[] { "Description", "Location", "Name", }); internal_static_a2a_v1_HTTPAuthSecurityScheme_descriptor = - getDescriptor().getMessageTypes().get(23); + getDescriptor().getMessageTypes().get(24); internal_static_a2a_v1_HTTPAuthSecurityScheme_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_HTTPAuthSecurityScheme_descriptor, new java.lang.String[] { "Description", "Scheme", "BearerFormat", }); internal_static_a2a_v1_OAuth2SecurityScheme_descriptor = - getDescriptor().getMessageTypes().get(24); + getDescriptor().getMessageTypes().get(25); internal_static_a2a_v1_OAuth2SecurityScheme_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_OAuth2SecurityScheme_descriptor, - new java.lang.String[] { "Description", "Flows", }); + new java.lang.String[] { "Description", "Flows", "Oauth2MetadataUrl", }); internal_static_a2a_v1_OpenIdConnectSecurityScheme_descriptor = - getDescriptor().getMessageTypes().get(25); + getDescriptor().getMessageTypes().get(26); internal_static_a2a_v1_OpenIdConnectSecurityScheme_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_OpenIdConnectSecurityScheme_descriptor, new java.lang.String[] { "Description", "OpenIdConnectUrl", }); + internal_static_a2a_v1_MutualTlsSecurityScheme_descriptor = + getDescriptor().getMessageTypes().get(27); + internal_static_a2a_v1_MutualTlsSecurityScheme_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_a2a_v1_MutualTlsSecurityScheme_descriptor, + new java.lang.String[] { "Description", }); internal_static_a2a_v1_OAuthFlows_descriptor = - getDescriptor().getMessageTypes().get(26); + getDescriptor().getMessageTypes().get(28); internal_static_a2a_v1_OAuthFlows_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_OAuthFlows_descriptor, new java.lang.String[] { "AuthorizationCode", "ClientCredentials", "Implicit", "Password", "Flow", }); internal_static_a2a_v1_AuthorizationCodeOAuthFlow_descriptor = - getDescriptor().getMessageTypes().get(27); + getDescriptor().getMessageTypes().get(29); internal_static_a2a_v1_AuthorizationCodeOAuthFlow_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_AuthorizationCodeOAuthFlow_descriptor, @@ -668,7 +699,7 @@ public static void registerAllExtensions( internal_static_a2a_v1_AuthorizationCodeOAuthFlow_ScopesEntry_descriptor, new java.lang.String[] { "Key", "Value", }); internal_static_a2a_v1_ClientCredentialsOAuthFlow_descriptor = - getDescriptor().getMessageTypes().get(28); + getDescriptor().getMessageTypes().get(30); internal_static_a2a_v1_ClientCredentialsOAuthFlow_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_ClientCredentialsOAuthFlow_descriptor, @@ -680,7 +711,7 @@ public static void registerAllExtensions( internal_static_a2a_v1_ClientCredentialsOAuthFlow_ScopesEntry_descriptor, new java.lang.String[] { "Key", "Value", }); internal_static_a2a_v1_ImplicitOAuthFlow_descriptor = - getDescriptor().getMessageTypes().get(29); + getDescriptor().getMessageTypes().get(31); internal_static_a2a_v1_ImplicitOAuthFlow_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_ImplicitOAuthFlow_descriptor, @@ -692,7 +723,7 @@ public static void registerAllExtensions( internal_static_a2a_v1_ImplicitOAuthFlow_ScopesEntry_descriptor, new java.lang.String[] { "Key", "Value", }); internal_static_a2a_v1_PasswordOAuthFlow_descriptor = - getDescriptor().getMessageTypes().get(30); + getDescriptor().getMessageTypes().get(32); internal_static_a2a_v1_PasswordOAuthFlow_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_PasswordOAuthFlow_descriptor, @@ -704,73 +735,73 @@ public static void registerAllExtensions( internal_static_a2a_v1_PasswordOAuthFlow_ScopesEntry_descriptor, new java.lang.String[] { "Key", "Value", }); internal_static_a2a_v1_SendMessageRequest_descriptor = - getDescriptor().getMessageTypes().get(31); + getDescriptor().getMessageTypes().get(33); internal_static_a2a_v1_SendMessageRequest_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_SendMessageRequest_descriptor, new java.lang.String[] { "Request", "Configuration", "Metadata", }); internal_static_a2a_v1_GetTaskRequest_descriptor = - getDescriptor().getMessageTypes().get(32); + getDescriptor().getMessageTypes().get(34); internal_static_a2a_v1_GetTaskRequest_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_GetTaskRequest_descriptor, new java.lang.String[] { "Name", "HistoryLength", }); internal_static_a2a_v1_CancelTaskRequest_descriptor = - getDescriptor().getMessageTypes().get(33); + getDescriptor().getMessageTypes().get(35); internal_static_a2a_v1_CancelTaskRequest_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_CancelTaskRequest_descriptor, new java.lang.String[] { "Name", }); internal_static_a2a_v1_GetTaskPushNotificationConfigRequest_descriptor = - getDescriptor().getMessageTypes().get(34); + getDescriptor().getMessageTypes().get(36); internal_static_a2a_v1_GetTaskPushNotificationConfigRequest_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_GetTaskPushNotificationConfigRequest_descriptor, new java.lang.String[] { "Name", }); internal_static_a2a_v1_DeleteTaskPushNotificationConfigRequest_descriptor = - getDescriptor().getMessageTypes().get(35); + getDescriptor().getMessageTypes().get(37); internal_static_a2a_v1_DeleteTaskPushNotificationConfigRequest_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_DeleteTaskPushNotificationConfigRequest_descriptor, new java.lang.String[] { "Name", }); internal_static_a2a_v1_CreateTaskPushNotificationConfigRequest_descriptor = - getDescriptor().getMessageTypes().get(36); + getDescriptor().getMessageTypes().get(38); internal_static_a2a_v1_CreateTaskPushNotificationConfigRequest_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_CreateTaskPushNotificationConfigRequest_descriptor, new java.lang.String[] { "Parent", "ConfigId", "Config", }); internal_static_a2a_v1_TaskSubscriptionRequest_descriptor = - getDescriptor().getMessageTypes().get(37); + getDescriptor().getMessageTypes().get(39); internal_static_a2a_v1_TaskSubscriptionRequest_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_TaskSubscriptionRequest_descriptor, new java.lang.String[] { "Name", }); internal_static_a2a_v1_ListTaskPushNotificationConfigRequest_descriptor = - getDescriptor().getMessageTypes().get(38); + getDescriptor().getMessageTypes().get(40); internal_static_a2a_v1_ListTaskPushNotificationConfigRequest_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_ListTaskPushNotificationConfigRequest_descriptor, new java.lang.String[] { "Parent", "PageSize", "PageToken", }); internal_static_a2a_v1_GetAgentCardRequest_descriptor = - getDescriptor().getMessageTypes().get(39); + getDescriptor().getMessageTypes().get(41); internal_static_a2a_v1_GetAgentCardRequest_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_GetAgentCardRequest_descriptor, new java.lang.String[] { }); internal_static_a2a_v1_SendMessageResponse_descriptor = - getDescriptor().getMessageTypes().get(40); + getDescriptor().getMessageTypes().get(42); internal_static_a2a_v1_SendMessageResponse_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_SendMessageResponse_descriptor, new java.lang.String[] { "Task", "Msg", "Payload", }); internal_static_a2a_v1_StreamResponse_descriptor = - getDescriptor().getMessageTypes().get(41); + getDescriptor().getMessageTypes().get(43); internal_static_a2a_v1_StreamResponse_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_StreamResponse_descriptor, new java.lang.String[] { "Task", "Msg", "StatusUpdate", "ArtifactUpdate", "Payload", }); internal_static_a2a_v1_ListTaskPushNotificationConfigResponse_descriptor = - getDescriptor().getMessageTypes().get(42); + getDescriptor().getMessageTypes().get(44); internal_static_a2a_v1_ListTaskPushNotificationConfigResponse_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_a2a_v1_ListTaskPushNotificationConfigResponse_descriptor, diff --git a/spec-grpc/src/main/java/io/a2a/grpc/AgentCard.java b/spec-grpc/src/main/java/io/a2a/grpc/AgentCard.java index 5862d4ef9..60d2cfb51 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/AgentCard.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/AgentCard.java @@ -12,6 +12,7 @@ * - Skills; a set of actions/solutions the agent can perform * - Default modalities/content types supported by the agent. * - Authentication requirements + * Next ID: 18 * * * Protobuf type {@code a2a.v1.AgentCard} @@ -50,6 +51,7 @@ private AgentCard() { defaultOutputModes_ = com.google.protobuf.LazyStringArrayList.emptyList(); skills_ = java.util.Collections.emptyList(); + signatures_ = java.util.Collections.emptyList(); } public static final com.google.protobuf.Descriptors.Descriptor @@ -659,6 +661,18 @@ public io.a2a.grpc.SecurityScheme getSecuritySchemesOrThrow( *
    * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
    * Security requirements for contacting the agent.
+   * This list can be seen as an OR of ANDs. Each object in the list describes
+   * one possible set of security requirements that must be present on a
+   * request. This allows specifying, for example, "callers must either use
+   * OAuth OR an API Key AND mTLS."
+   * Example:
+   * security {
+   * schemes { key: "oauth" value { list: ["read"] } }
+   * }
+   * security {
+   * schemes { key: "api-key" }
+   * schemes { key: "mtls" }
+   * }
    * 
* * repeated .a2a.v1.Security security = 9; @@ -671,6 +685,18 @@ public java.util.List getSecurityList() { *
    * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
    * Security requirements for contacting the agent.
+   * This list can be seen as an OR of ANDs. Each object in the list describes
+   * one possible set of security requirements that must be present on a
+   * request. This allows specifying, for example, "callers must either use
+   * OAuth OR an API Key AND mTLS."
+   * Example:
+   * security {
+   * schemes { key: "oauth" value { list: ["read"] } }
+   * }
+   * security {
+   * schemes { key: "api-key" }
+   * schemes { key: "mtls" }
+   * }
    * 
* * repeated .a2a.v1.Security security = 9; @@ -684,6 +710,18 @@ public java.util.List getSecurityList() { *
    * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
    * Security requirements for contacting the agent.
+   * This list can be seen as an OR of ANDs. Each object in the list describes
+   * one possible set of security requirements that must be present on a
+   * request. This allows specifying, for example, "callers must either use
+   * OAuth OR an API Key AND mTLS."
+   * Example:
+   * security {
+   * schemes { key: "oauth" value { list: ["read"] } }
+   * }
+   * security {
+   * schemes { key: "api-key" }
+   * schemes { key: "mtls" }
+   * }
    * 
* * repeated .a2a.v1.Security security = 9; @@ -696,6 +734,18 @@ public int getSecurityCount() { *
    * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
    * Security requirements for contacting the agent.
+   * This list can be seen as an OR of ANDs. Each object in the list describes
+   * one possible set of security requirements that must be present on a
+   * request. This allows specifying, for example, "callers must either use
+   * OAuth OR an API Key AND mTLS."
+   * Example:
+   * security {
+   * schemes { key: "oauth" value { list: ["read"] } }
+   * }
+   * security {
+   * schemes { key: "api-key" }
+   * schemes { key: "mtls" }
+   * }
    * 
* * repeated .a2a.v1.Security security = 9; @@ -708,6 +758,18 @@ public io.a2a.grpc.Security getSecurity(int index) { *
    * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
    * Security requirements for contacting the agent.
+   * This list can be seen as an OR of ANDs. Each object in the list describes
+   * one possible set of security requirements that must be present on a
+   * request. This allows specifying, for example, "callers must either use
+   * OAuth OR an API Key AND mTLS."
+   * Example:
+   * security {
+   * schemes { key: "oauth" value { list: ["read"] } }
+   * }
+   * security {
+   * schemes { key: "api-key" }
+   * schemes { key: "mtls" }
+   * }
    * 
* * repeated .a2a.v1.Security security = 9; @@ -920,6 +982,67 @@ public boolean getSupportsAuthenticatedExtendedCard() { return supportsAuthenticatedExtendedCard_; } + public static final int SIGNATURES_FIELD_NUMBER = 17; + @SuppressWarnings("serial") + private java.util.List signatures_; + /** + *
+   * JSON Web Signatures computed for this AgentCard.
+   * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + @java.lang.Override + public java.util.List getSignaturesList() { + return signatures_; + } + /** + *
+   * JSON Web Signatures computed for this AgentCard.
+   * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + @java.lang.Override + public java.util.List + getSignaturesOrBuilderList() { + return signatures_; + } + /** + *
+   * JSON Web Signatures computed for this AgentCard.
+   * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + @java.lang.Override + public int getSignaturesCount() { + return signatures_.size(); + } + /** + *
+   * JSON Web Signatures computed for this AgentCard.
+   * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + @java.lang.Override + public io.a2a.grpc.AgentCardSignature getSignatures(int index) { + return signatures_.get(index); + } + /** + *
+   * JSON Web Signatures computed for this AgentCard.
+   * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + @java.lang.Override + public io.a2a.grpc.AgentCardSignatureOrBuilder getSignaturesOrBuilder( + int index) { + return signatures_.get(index); + } + private byte memoizedIsInitialized = -1; @java.lang.Override public final boolean isInitialized() { @@ -985,6 +1108,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (!com.google.protobuf.GeneratedMessage.isStringEmpty(protocolVersion_)) { com.google.protobuf.GeneratedMessage.writeString(output, 16, protocolVersion_); } + for (int i = 0; i < signatures_.size(); i++) { + output.writeMessage(17, signatures_.get(i)); + } getUnknownFields().writeTo(output); } @@ -1065,6 +1191,10 @@ public int getSerializedSize() { if (!com.google.protobuf.GeneratedMessage.isStringEmpty(protocolVersion_)) { size += com.google.protobuf.GeneratedMessage.computeStringSize(16, protocolVersion_); } + for (int i = 0; i < signatures_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(17, signatures_.get(i)); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -1118,6 +1248,8 @@ public boolean equals(final java.lang.Object obj) { .equals(other.getSkillsList())) return false; if (getSupportsAuthenticatedExtendedCard() != other.getSupportsAuthenticatedExtendedCard()) return false; + if (!getSignaturesList() + .equals(other.getSignaturesList())) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -1178,6 +1310,10 @@ public int hashCode() { hash = (37 * hash) + SUPPORTS_AUTHENTICATED_EXTENDED_CARD_FIELD_NUMBER; hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( getSupportsAuthenticatedExtendedCard()); + if (getSignaturesCount() > 0) { + hash = (37 * hash) + SIGNATURES_FIELD_NUMBER; + hash = (53 * hash) + getSignaturesList().hashCode(); + } hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -1282,6 +1418,7 @@ protected Builder newBuilderForType( * - Skills; a set of actions/solutions the agent can perform * - Default modalities/content types supported by the agent. * - Authentication requirements + * Next ID: 18 * * * Protobuf type {@code a2a.v1.AgentCard} @@ -1343,6 +1480,7 @@ private void maybeForceBuilderInitialization() { internalGetCapabilitiesFieldBuilder(); internalGetSecurityFieldBuilder(); internalGetSkillsFieldBuilder(); + internalGetSignaturesFieldBuilder(); } } @java.lang.Override @@ -1393,6 +1531,13 @@ public Builder clear() { } bitField0_ = (bitField0_ & ~0x00004000); supportsAuthenticatedExtendedCard_ = false; + if (signaturesBuilder_ == null) { + signatures_ = java.util.Collections.emptyList(); + } else { + signatures_ = null; + signaturesBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00010000); return this; } @@ -1453,6 +1598,15 @@ private void buildPartialRepeatedFields(io.a2a.grpc.AgentCard result) { } else { result.skills_ = skillsBuilder_.build(); } + if (signaturesBuilder_ == null) { + if (((bitField0_ & 0x00010000) != 0)) { + signatures_ = java.util.Collections.unmodifiableList(signatures_); + bitField0_ = (bitField0_ & ~0x00010000); + } + result.signatures_ = signatures_; + } else { + result.signatures_ = signaturesBuilder_.build(); + } } private void buildPartial0(io.a2a.grpc.AgentCard result) { @@ -1665,6 +1819,32 @@ public Builder mergeFrom(io.a2a.grpc.AgentCard other) { if (other.getSupportsAuthenticatedExtendedCard() != false) { setSupportsAuthenticatedExtendedCard(other.getSupportsAuthenticatedExtendedCard()); } + if (signaturesBuilder_ == null) { + if (!other.signatures_.isEmpty()) { + if (signatures_.isEmpty()) { + signatures_ = other.signatures_; + bitField0_ = (bitField0_ & ~0x00010000); + } else { + ensureSignaturesIsMutable(); + signatures_.addAll(other.signatures_); + } + onChanged(); + } + } else { + if (!other.signatures_.isEmpty()) { + if (signaturesBuilder_.isEmpty()) { + signaturesBuilder_.dispose(); + signaturesBuilder_ = null; + signatures_ = other.signatures_; + bitField0_ = (bitField0_ & ~0x00010000); + signaturesBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + internalGetSignaturesFieldBuilder() : null; + } else { + signaturesBuilder_.addAllMessages(other.signatures_); + } + } + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -1805,6 +1985,19 @@ public Builder mergeFrom( bitField0_ |= 0x00000001; break; } // case 130 + case 138: { + io.a2a.grpc.AgentCardSignature m = + input.readMessage( + io.a2a.grpc.AgentCardSignature.parser(), + extensionRegistry); + if (signaturesBuilder_ == null) { + ensureSignaturesIsMutable(); + signatures_.add(m); + } else { + signaturesBuilder_.addMessage(m); + } + break; + } // case 138 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -3333,6 +3526,18 @@ private void ensureSecurityIsMutable() { *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3348,6 +3553,18 @@ public java.util.List getSecurityList() { *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3363,6 +3580,18 @@ public int getSecurityCount() { *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3378,6 +3607,18 @@ public io.a2a.grpc.Security getSecurity(int index) { *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3400,6 +3641,18 @@ public Builder setSecurity( *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3419,6 +3672,18 @@ public Builder setSecurity( *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3440,6 +3705,18 @@ public Builder addSecurity(io.a2a.grpc.Security value) { *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3462,6 +3739,18 @@ public Builder addSecurity( *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3481,6 +3770,18 @@ public Builder addSecurity( *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3500,6 +3801,18 @@ public Builder addSecurity( *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3520,6 +3833,18 @@ public Builder addAllSecurity( *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3538,6 +3863,18 @@ public Builder clearSecurity() { *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3556,6 +3893,18 @@ public Builder removeSecurity(int index) { *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3568,6 +3917,18 @@ public io.a2a.grpc.Security.Builder getSecurityBuilder( *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3583,6 +3944,18 @@ public io.a2a.grpc.SecurityOrBuilder getSecurityOrBuilder( *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3599,6 +3972,18 @@ public io.a2a.grpc.SecurityOrBuilder getSecurityOrBuilder( *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3611,6 +3996,18 @@ public io.a2a.grpc.Security.Builder addSecurityBuilder() { *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -3624,6 +4021,18 @@ public io.a2a.grpc.Security.Builder addSecurityBuilder( *
      * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
      * Security requirements for contacting the agent.
+     * This list can be seen as an OR of ANDs. Each object in the list describes
+     * one possible set of security requirements that must be present on a
+     * request. This allows specifying, for example, "callers must either use
+     * OAuth OR an API Key AND mTLS."
+     * Example:
+     * security {
+     * schemes { key: "oauth" value { list: ["read"] } }
+     * }
+     * security {
+     * schemes { key: "api-key" }
+     * schemes { key: "mtls" }
+     * }
      * 
* * repeated .a2a.v1.Security security = 9; @@ -4357,6 +4766,318 @@ public Builder clearSupportsAuthenticatedExtendedCard() { return this; } + private java.util.List signatures_ = + java.util.Collections.emptyList(); + private void ensureSignaturesIsMutable() { + if (!((bitField0_ & 0x00010000) != 0)) { + signatures_ = new java.util.ArrayList(signatures_); + bitField0_ |= 0x00010000; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + io.a2a.grpc.AgentCardSignature, io.a2a.grpc.AgentCardSignature.Builder, io.a2a.grpc.AgentCardSignatureOrBuilder> signaturesBuilder_; + + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public java.util.List getSignaturesList() { + if (signaturesBuilder_ == null) { + return java.util.Collections.unmodifiableList(signatures_); + } else { + return signaturesBuilder_.getMessageList(); + } + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public int getSignaturesCount() { + if (signaturesBuilder_ == null) { + return signatures_.size(); + } else { + return signaturesBuilder_.getCount(); + } + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public io.a2a.grpc.AgentCardSignature getSignatures(int index) { + if (signaturesBuilder_ == null) { + return signatures_.get(index); + } else { + return signaturesBuilder_.getMessage(index); + } + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public Builder setSignatures( + int index, io.a2a.grpc.AgentCardSignature value) { + if (signaturesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSignaturesIsMutable(); + signatures_.set(index, value); + onChanged(); + } else { + signaturesBuilder_.setMessage(index, value); + } + return this; + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public Builder setSignatures( + int index, io.a2a.grpc.AgentCardSignature.Builder builderForValue) { + if (signaturesBuilder_ == null) { + ensureSignaturesIsMutable(); + signatures_.set(index, builderForValue.build()); + onChanged(); + } else { + signaturesBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public Builder addSignatures(io.a2a.grpc.AgentCardSignature value) { + if (signaturesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSignaturesIsMutable(); + signatures_.add(value); + onChanged(); + } else { + signaturesBuilder_.addMessage(value); + } + return this; + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public Builder addSignatures( + int index, io.a2a.grpc.AgentCardSignature value) { + if (signaturesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSignaturesIsMutable(); + signatures_.add(index, value); + onChanged(); + } else { + signaturesBuilder_.addMessage(index, value); + } + return this; + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public Builder addSignatures( + io.a2a.grpc.AgentCardSignature.Builder builderForValue) { + if (signaturesBuilder_ == null) { + ensureSignaturesIsMutable(); + signatures_.add(builderForValue.build()); + onChanged(); + } else { + signaturesBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public Builder addSignatures( + int index, io.a2a.grpc.AgentCardSignature.Builder builderForValue) { + if (signaturesBuilder_ == null) { + ensureSignaturesIsMutable(); + signatures_.add(index, builderForValue.build()); + onChanged(); + } else { + signaturesBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public Builder addAllSignatures( + java.lang.Iterable values) { + if (signaturesBuilder_ == null) { + ensureSignaturesIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, signatures_); + onChanged(); + } else { + signaturesBuilder_.addAllMessages(values); + } + return this; + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public Builder clearSignatures() { + if (signaturesBuilder_ == null) { + signatures_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00010000); + onChanged(); + } else { + signaturesBuilder_.clear(); + } + return this; + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public Builder removeSignatures(int index) { + if (signaturesBuilder_ == null) { + ensureSignaturesIsMutable(); + signatures_.remove(index); + onChanged(); + } else { + signaturesBuilder_.remove(index); + } + return this; + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public io.a2a.grpc.AgentCardSignature.Builder getSignaturesBuilder( + int index) { + return internalGetSignaturesFieldBuilder().getBuilder(index); + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public io.a2a.grpc.AgentCardSignatureOrBuilder getSignaturesOrBuilder( + int index) { + if (signaturesBuilder_ == null) { + return signatures_.get(index); } else { + return signaturesBuilder_.getMessageOrBuilder(index); + } + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public java.util.List + getSignaturesOrBuilderList() { + if (signaturesBuilder_ != null) { + return signaturesBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(signatures_); + } + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public io.a2a.grpc.AgentCardSignature.Builder addSignaturesBuilder() { + return internalGetSignaturesFieldBuilder().addBuilder( + io.a2a.grpc.AgentCardSignature.getDefaultInstance()); + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public io.a2a.grpc.AgentCardSignature.Builder addSignaturesBuilder( + int index) { + return internalGetSignaturesFieldBuilder().addBuilder( + index, io.a2a.grpc.AgentCardSignature.getDefaultInstance()); + } + /** + *
+     * JSON Web Signatures computed for this AgentCard.
+     * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + public java.util.List + getSignaturesBuilderList() { + return internalGetSignaturesFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + io.a2a.grpc.AgentCardSignature, io.a2a.grpc.AgentCardSignature.Builder, io.a2a.grpc.AgentCardSignatureOrBuilder> + internalGetSignaturesFieldBuilder() { + if (signaturesBuilder_ == null) { + signaturesBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + io.a2a.grpc.AgentCardSignature, io.a2a.grpc.AgentCardSignature.Builder, io.a2a.grpc.AgentCardSignatureOrBuilder>( + signatures_, + ((bitField0_ & 0x00010000) != 0), + getParentForChildren(), + isClean()); + signatures_ = null; + } + return signaturesBuilder_; + } + // @@protoc_insertion_point(builder_scope:a2a.v1.AgentCard) } diff --git a/spec-grpc/src/main/java/io/a2a/grpc/AgentCardOrBuilder.java b/spec-grpc/src/main/java/io/a2a/grpc/AgentCardOrBuilder.java index 6a992f83e..3ad50a5fd 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/AgentCardOrBuilder.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/AgentCardOrBuilder.java @@ -319,6 +319,18 @@ io.a2a.grpc.SecurityScheme getSecuritySchemesOrThrow( *
    * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
    * Security requirements for contacting the agent.
+   * This list can be seen as an OR of ANDs. Each object in the list describes
+   * one possible set of security requirements that must be present on a
+   * request. This allows specifying, for example, "callers must either use
+   * OAuth OR an API Key AND mTLS."
+   * Example:
+   * security {
+   * schemes { key: "oauth" value { list: ["read"] } }
+   * }
+   * security {
+   * schemes { key: "api-key" }
+   * schemes { key: "mtls" }
+   * }
    * 
* * repeated .a2a.v1.Security security = 9; @@ -329,6 +341,18 @@ io.a2a.grpc.SecurityScheme getSecuritySchemesOrThrow( *
    * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
    * Security requirements for contacting the agent.
+   * This list can be seen as an OR of ANDs. Each object in the list describes
+   * one possible set of security requirements that must be present on a
+   * request. This allows specifying, for example, "callers must either use
+   * OAuth OR an API Key AND mTLS."
+   * Example:
+   * security {
+   * schemes { key: "oauth" value { list: ["read"] } }
+   * }
+   * security {
+   * schemes { key: "api-key" }
+   * schemes { key: "mtls" }
+   * }
    * 
* * repeated .a2a.v1.Security security = 9; @@ -338,6 +362,18 @@ io.a2a.grpc.SecurityScheme getSecuritySchemesOrThrow( *
    * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
    * Security requirements for contacting the agent.
+   * This list can be seen as an OR of ANDs. Each object in the list describes
+   * one possible set of security requirements that must be present on a
+   * request. This allows specifying, for example, "callers must either use
+   * OAuth OR an API Key AND mTLS."
+   * Example:
+   * security {
+   * schemes { key: "oauth" value { list: ["read"] } }
+   * }
+   * security {
+   * schemes { key: "api-key" }
+   * schemes { key: "mtls" }
+   * }
    * 
* * repeated .a2a.v1.Security security = 9; @@ -347,6 +383,18 @@ io.a2a.grpc.SecurityScheme getSecuritySchemesOrThrow( *
    * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
    * Security requirements for contacting the agent.
+   * This list can be seen as an OR of ANDs. Each object in the list describes
+   * one possible set of security requirements that must be present on a
+   * request. This allows specifying, for example, "callers must either use
+   * OAuth OR an API Key AND mTLS."
+   * Example:
+   * security {
+   * schemes { key: "oauth" value { list: ["read"] } }
+   * }
+   * security {
+   * schemes { key: "api-key" }
+   * schemes { key: "mtls" }
+   * }
    * 
* * repeated .a2a.v1.Security security = 9; @@ -357,6 +405,18 @@ io.a2a.grpc.SecurityScheme getSecuritySchemesOrThrow( *
    * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
    * Security requirements for contacting the agent.
+   * This list can be seen as an OR of ANDs. Each object in the list describes
+   * one possible set of security requirements that must be present on a
+   * request. This allows specifying, for example, "callers must either use
+   * OAuth OR an API Key AND mTLS."
+   * Example:
+   * security {
+   * schemes { key: "oauth" value { list: ["read"] } }
+   * }
+   * security {
+   * schemes { key: "api-key" }
+   * schemes { key: "mtls" }
+   * }
    * 
* * repeated .a2a.v1.Security security = 9; @@ -519,4 +579,48 @@ io.a2a.grpc.AgentSkillOrBuilder getSkillsOrBuilder( * @return The supportsAuthenticatedExtendedCard. */ boolean getSupportsAuthenticatedExtendedCard(); + + /** + *
+   * JSON Web Signatures computed for this AgentCard.
+   * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + java.util.List + getSignaturesList(); + /** + *
+   * JSON Web Signatures computed for this AgentCard.
+   * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + io.a2a.grpc.AgentCardSignature getSignatures(int index); + /** + *
+   * JSON Web Signatures computed for this AgentCard.
+   * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + int getSignaturesCount(); + /** + *
+   * JSON Web Signatures computed for this AgentCard.
+   * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + java.util.List + getSignaturesOrBuilderList(); + /** + *
+   * JSON Web Signatures computed for this AgentCard.
+   * 
+ * + * repeated .a2a.v1.AgentCardSignature signatures = 17; + */ + io.a2a.grpc.AgentCardSignatureOrBuilder getSignaturesOrBuilder( + int index); } diff --git a/spec-grpc/src/main/java/io/a2a/grpc/AgentCardSignature.java b/spec-grpc/src/main/java/io/a2a/grpc/AgentCardSignature.java new file mode 100644 index 000000000..790bcd941 --- /dev/null +++ b/spec-grpc/src/main/java/io/a2a/grpc/AgentCardSignature.java @@ -0,0 +1,952 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// NO CHECKED-IN PROTOBUF GENCODE +// source: a2a.proto +// Protobuf Java Version: 4.31.1 + +package io.a2a.grpc; + +/** + *
+ * AgentCardSignature represents a JWS signature of an AgentCard.
+ * This follows the JSON format of an RFC 7515 JSON Web Signature (JWS).
+ * 
+ * + * Protobuf type {@code a2a.v1.AgentCardSignature} + */ +@com.google.protobuf.Generated +public final class AgentCardSignature extends + com.google.protobuf.GeneratedMessage implements + // @@protoc_insertion_point(message_implements:a2a.v1.AgentCardSignature) + AgentCardSignatureOrBuilder { +private static final long serialVersionUID = 0L; + static { + com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( + com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, + /* major= */ 4, + /* minor= */ 31, + /* patch= */ 1, + /* suffix= */ "", + AgentCardSignature.class.getName()); + } + // Use AgentCardSignature.newBuilder() to construct. + private AgentCardSignature(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + } + private AgentCardSignature() { + protected_ = ""; + signature_ = ""; + } + + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return io.a2a.grpc.A2A.internal_static_a2a_v1_AgentCardSignature_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.a2a.grpc.A2A.internal_static_a2a_v1_AgentCardSignature_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.a2a.grpc.AgentCardSignature.class, io.a2a.grpc.AgentCardSignature.Builder.class); + } + + private int bitField0_; + public static final int PROTECTED_FIELD_NUMBER = 1; + @SuppressWarnings("serial") + private volatile java.lang.Object protected_ = ""; + /** + *
+   * The protected JWS header for the signature. This is always a
+   * base64url-encoded JSON object. Required.
+   * 
+ * + * string protected = 1 [(.google.api.field_behavior) = REQUIRED]; + * @return The protected. + */ + @java.lang.Override + public java.lang.String getProtected() { + java.lang.Object ref = protected_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + protected_ = s; + return s; + } + } + /** + *
+   * The protected JWS header for the signature. This is always a
+   * base64url-encoded JSON object. Required.
+   * 
+ * + * string protected = 1 [(.google.api.field_behavior) = REQUIRED]; + * @return The bytes for protected. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getProtectedBytes() { + java.lang.Object ref = protected_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + protected_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int SIGNATURE_FIELD_NUMBER = 2; + @SuppressWarnings("serial") + private volatile java.lang.Object signature_ = ""; + /** + *
+   * The computed signature, base64url-encoded. Required.
+   * 
+ * + * string signature = 2 [(.google.api.field_behavior) = REQUIRED]; + * @return The signature. + */ + @java.lang.Override + public java.lang.String getSignature() { + java.lang.Object ref = signature_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + signature_ = s; + return s; + } + } + /** + *
+   * The computed signature, base64url-encoded. Required.
+   * 
+ * + * string signature = 2 [(.google.api.field_behavior) = REQUIRED]; + * @return The bytes for signature. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getSignatureBytes() { + java.lang.Object ref = signature_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + signature_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int HEADER_FIELD_NUMBER = 3; + private com.google.protobuf.Struct header_; + /** + *
+   * The unprotected JWS header values.
+   * 
+ * + * .google.protobuf.Struct header = 3; + * @return Whether the header field is set. + */ + @java.lang.Override + public boolean hasHeader() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + *
+   * The unprotected JWS header values.
+   * 
+ * + * .google.protobuf.Struct header = 3; + * @return The header. + */ + @java.lang.Override + public com.google.protobuf.Struct getHeader() { + return header_ == null ? com.google.protobuf.Struct.getDefaultInstance() : header_; + } + /** + *
+   * The unprotected JWS header values.
+   * 
+ * + * .google.protobuf.Struct header = 3; + */ + @java.lang.Override + public com.google.protobuf.StructOrBuilder getHeaderOrBuilder() { + return header_ == null ? com.google.protobuf.Struct.getDefaultInstance() : header_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessage.isStringEmpty(protected_)) { + com.google.protobuf.GeneratedMessage.writeString(output, 1, protected_); + } + if (!com.google.protobuf.GeneratedMessage.isStringEmpty(signature_)) { + com.google.protobuf.GeneratedMessage.writeString(output, 2, signature_); + } + if (((bitField0_ & 0x00000001) != 0)) { + output.writeMessage(3, getHeader()); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessage.isStringEmpty(protected_)) { + size += com.google.protobuf.GeneratedMessage.computeStringSize(1, protected_); + } + if (!com.google.protobuf.GeneratedMessage.isStringEmpty(signature_)) { + size += com.google.protobuf.GeneratedMessage.computeStringSize(2, signature_); + } + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, getHeader()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.a2a.grpc.AgentCardSignature)) { + return super.equals(obj); + } + io.a2a.grpc.AgentCardSignature other = (io.a2a.grpc.AgentCardSignature) obj; + + if (!getProtected() + .equals(other.getProtected())) return false; + if (!getSignature() + .equals(other.getSignature())) return false; + if (hasHeader() != other.hasHeader()) return false; + if (hasHeader()) { + if (!getHeader() + .equals(other.getHeader())) return false; + } + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + PROTECTED_FIELD_NUMBER; + hash = (53 * hash) + getProtected().hashCode(); + hash = (37 * hash) + SIGNATURE_FIELD_NUMBER; + hash = (53 * hash) + getSignature().hashCode(); + if (hasHeader()) { + hash = (37 * hash) + HEADER_FIELD_NUMBER; + hash = (53 * hash) + getHeader().hashCode(); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.a2a.grpc.AgentCardSignature parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.a2a.grpc.AgentCardSignature parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.a2a.grpc.AgentCardSignature parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.a2a.grpc.AgentCardSignature parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.a2a.grpc.AgentCardSignature parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.a2a.grpc.AgentCardSignature parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.a2a.grpc.AgentCardSignature parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input); + } + public static io.a2a.grpc.AgentCardSignature parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public static io.a2a.grpc.AgentCardSignature parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseDelimitedWithIOException(PARSER, input); + } + + public static io.a2a.grpc.AgentCardSignature parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.a2a.grpc.AgentCardSignature parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input); + } + public static io.a2a.grpc.AgentCardSignature parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.a2a.grpc.AgentCardSignature prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+   * AgentCardSignature represents a JWS signature of an AgentCard.
+   * This follows the JSON format of an RFC 7515 JSON Web Signature (JWS).
+   * 
+ * + * Protobuf type {@code a2a.v1.AgentCardSignature} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder implements + // @@protoc_insertion_point(builder_implements:a2a.v1.AgentCardSignature) + io.a2a.grpc.AgentCardSignatureOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return io.a2a.grpc.A2A.internal_static_a2a_v1_AgentCardSignature_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.a2a.grpc.A2A.internal_static_a2a_v1_AgentCardSignature_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.a2a.grpc.AgentCardSignature.class, io.a2a.grpc.AgentCardSignature.Builder.class); + } + + // Construct using io.a2a.grpc.AgentCardSignature.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage + .alwaysUseFieldBuilders) { + internalGetHeaderFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + protected_ = ""; + signature_ = ""; + header_ = null; + if (headerBuilder_ != null) { + headerBuilder_.dispose(); + headerBuilder_ = null; + } + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return io.a2a.grpc.A2A.internal_static_a2a_v1_AgentCardSignature_descriptor; + } + + @java.lang.Override + public io.a2a.grpc.AgentCardSignature getDefaultInstanceForType() { + return io.a2a.grpc.AgentCardSignature.getDefaultInstance(); + } + + @java.lang.Override + public io.a2a.grpc.AgentCardSignature build() { + io.a2a.grpc.AgentCardSignature result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.a2a.grpc.AgentCardSignature buildPartial() { + io.a2a.grpc.AgentCardSignature result = new io.a2a.grpc.AgentCardSignature(this); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartial0(io.a2a.grpc.AgentCardSignature result) { + int from_bitField0_ = bitField0_; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.protected_ = protected_; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.signature_ = signature_; + } + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000004) != 0)) { + result.header_ = headerBuilder_ == null + ? header_ + : headerBuilder_.build(); + to_bitField0_ |= 0x00000001; + } + result.bitField0_ |= to_bitField0_; + } + + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof io.a2a.grpc.AgentCardSignature) { + return mergeFrom((io.a2a.grpc.AgentCardSignature)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.a2a.grpc.AgentCardSignature other) { + if (other == io.a2a.grpc.AgentCardSignature.getDefaultInstance()) return this; + if (!other.getProtected().isEmpty()) { + protected_ = other.protected_; + bitField0_ |= 0x00000001; + onChanged(); + } + if (!other.getSignature().isEmpty()) { + signature_ = other.signature_; + bitField0_ |= 0x00000002; + onChanged(); + } + if (other.hasHeader()) { + mergeHeader(other.getHeader()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + protected_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000001; + break; + } // case 10 + case 18: { + signature_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000002; + break; + } // case 18 + case 26: { + input.readMessage( + internalGetHeaderFieldBuilder().getBuilder(), + extensionRegistry); + bitField0_ |= 0x00000004; + break; + } // case 26 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private java.lang.Object protected_ = ""; + /** + *
+     * The protected JWS header for the signature. This is always a
+     * base64url-encoded JSON object. Required.
+     * 
+ * + * string protected = 1 [(.google.api.field_behavior) = REQUIRED]; + * @return The protected. + */ + public java.lang.String getProtected() { + java.lang.Object ref = protected_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + protected_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+     * The protected JWS header for the signature. This is always a
+     * base64url-encoded JSON object. Required.
+     * 
+ * + * string protected = 1 [(.google.api.field_behavior) = REQUIRED]; + * @return The bytes for protected. + */ + public com.google.protobuf.ByteString + getProtectedBytes() { + java.lang.Object ref = protected_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + protected_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+     * The protected JWS header for the signature. This is always a
+     * base64url-encoded JSON object. Required.
+     * 
+ * + * string protected = 1 [(.google.api.field_behavior) = REQUIRED]; + * @param value The protected to set. + * @return This builder for chaining. + */ + public Builder setProtected( + java.lang.String value) { + if (value == null) { throw new NullPointerException(); } + protected_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + *
+     * The protected JWS header for the signature. This is always a
+     * base64url-encoded JSON object. Required.
+     * 
+ * + * string protected = 1 [(.google.api.field_behavior) = REQUIRED]; + * @return This builder for chaining. + */ + public Builder clearProtected() { + protected_ = getDefaultInstance().getProtected(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + *
+     * The protected JWS header for the signature. This is always a
+     * base64url-encoded JSON object. Required.
+     * 
+ * + * string protected = 1 [(.google.api.field_behavior) = REQUIRED]; + * @param value The bytes for protected to set. + * @return This builder for chaining. + */ + public Builder setProtectedBytes( + com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + checkByteStringIsUtf8(value); + protected_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + + private java.lang.Object signature_ = ""; + /** + *
+     * The computed signature, base64url-encoded. Required.
+     * 
+ * + * string signature = 2 [(.google.api.field_behavior) = REQUIRED]; + * @return The signature. + */ + public java.lang.String getSignature() { + java.lang.Object ref = signature_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + signature_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+     * The computed signature, base64url-encoded. Required.
+     * 
+ * + * string signature = 2 [(.google.api.field_behavior) = REQUIRED]; + * @return The bytes for signature. + */ + public com.google.protobuf.ByteString + getSignatureBytes() { + java.lang.Object ref = signature_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + signature_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+     * The computed signature, base64url-encoded. Required.
+     * 
+ * + * string signature = 2 [(.google.api.field_behavior) = REQUIRED]; + * @param value The signature to set. + * @return This builder for chaining. + */ + public Builder setSignature( + java.lang.String value) { + if (value == null) { throw new NullPointerException(); } + signature_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + *
+     * The computed signature, base64url-encoded. Required.
+     * 
+ * + * string signature = 2 [(.google.api.field_behavior) = REQUIRED]; + * @return This builder for chaining. + */ + public Builder clearSignature() { + signature_ = getDefaultInstance().getSignature(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + return this; + } + /** + *
+     * The computed signature, base64url-encoded. Required.
+     * 
+ * + * string signature = 2 [(.google.api.field_behavior) = REQUIRED]; + * @param value The bytes for signature to set. + * @return This builder for chaining. + */ + public Builder setSignatureBytes( + com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + checkByteStringIsUtf8(value); + signature_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + + private com.google.protobuf.Struct header_; + private com.google.protobuf.SingleFieldBuilder< + com.google.protobuf.Struct, com.google.protobuf.Struct.Builder, com.google.protobuf.StructOrBuilder> headerBuilder_; + /** + *
+     * The unprotected JWS header values.
+     * 
+ * + * .google.protobuf.Struct header = 3; + * @return Whether the header field is set. + */ + public boolean hasHeader() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + *
+     * The unprotected JWS header values.
+     * 
+ * + * .google.protobuf.Struct header = 3; + * @return The header. + */ + public com.google.protobuf.Struct getHeader() { + if (headerBuilder_ == null) { + return header_ == null ? com.google.protobuf.Struct.getDefaultInstance() : header_; + } else { + return headerBuilder_.getMessage(); + } + } + /** + *
+     * The unprotected JWS header values.
+     * 
+ * + * .google.protobuf.Struct header = 3; + */ + public Builder setHeader(com.google.protobuf.Struct value) { + if (headerBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + header_ = value; + } else { + headerBuilder_.setMessage(value); + } + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + *
+     * The unprotected JWS header values.
+     * 
+ * + * .google.protobuf.Struct header = 3; + */ + public Builder setHeader( + com.google.protobuf.Struct.Builder builderForValue) { + if (headerBuilder_ == null) { + header_ = builderForValue.build(); + } else { + headerBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + *
+     * The unprotected JWS header values.
+     * 
+ * + * .google.protobuf.Struct header = 3; + */ + public Builder mergeHeader(com.google.protobuf.Struct value) { + if (headerBuilder_ == null) { + if (((bitField0_ & 0x00000004) != 0) && + header_ != null && + header_ != com.google.protobuf.Struct.getDefaultInstance()) { + getHeaderBuilder().mergeFrom(value); + } else { + header_ = value; + } + } else { + headerBuilder_.mergeFrom(value); + } + if (header_ != null) { + bitField0_ |= 0x00000004; + onChanged(); + } + return this; + } + /** + *
+     * The unprotected JWS header values.
+     * 
+ * + * .google.protobuf.Struct header = 3; + */ + public Builder clearHeader() { + bitField0_ = (bitField0_ & ~0x00000004); + header_ = null; + if (headerBuilder_ != null) { + headerBuilder_.dispose(); + headerBuilder_ = null; + } + onChanged(); + return this; + } + /** + *
+     * The unprotected JWS header values.
+     * 
+ * + * .google.protobuf.Struct header = 3; + */ + public com.google.protobuf.Struct.Builder getHeaderBuilder() { + bitField0_ |= 0x00000004; + onChanged(); + return internalGetHeaderFieldBuilder().getBuilder(); + } + /** + *
+     * The unprotected JWS header values.
+     * 
+ * + * .google.protobuf.Struct header = 3; + */ + public com.google.protobuf.StructOrBuilder getHeaderOrBuilder() { + if (headerBuilder_ != null) { + return headerBuilder_.getMessageOrBuilder(); + } else { + return header_ == null ? + com.google.protobuf.Struct.getDefaultInstance() : header_; + } + } + /** + *
+     * The unprotected JWS header values.
+     * 
+ * + * .google.protobuf.Struct header = 3; + */ + private com.google.protobuf.SingleFieldBuilder< + com.google.protobuf.Struct, com.google.protobuf.Struct.Builder, com.google.protobuf.StructOrBuilder> + internalGetHeaderFieldBuilder() { + if (headerBuilder_ == null) { + headerBuilder_ = new com.google.protobuf.SingleFieldBuilder< + com.google.protobuf.Struct, com.google.protobuf.Struct.Builder, com.google.protobuf.StructOrBuilder>( + getHeader(), + getParentForChildren(), + isClean()); + header_ = null; + } + return headerBuilder_; + } + + // @@protoc_insertion_point(builder_scope:a2a.v1.AgentCardSignature) + } + + // @@protoc_insertion_point(class_scope:a2a.v1.AgentCardSignature) + private static final io.a2a.grpc.AgentCardSignature DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.a2a.grpc.AgentCardSignature(); + } + + public static io.a2a.grpc.AgentCardSignature getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public AgentCardSignature parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.a2a.grpc.AgentCardSignature getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/spec-grpc/src/main/java/io/a2a/grpc/AgentCardSignatureOrBuilder.java b/spec-grpc/src/main/java/io/a2a/grpc/AgentCardSignatureOrBuilder.java new file mode 100644 index 000000000..d863a9917 --- /dev/null +++ b/spec-grpc/src/main/java/io/a2a/grpc/AgentCardSignatureOrBuilder.java @@ -0,0 +1,81 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// NO CHECKED-IN PROTOBUF GENCODE +// source: a2a.proto +// Protobuf Java Version: 4.31.1 + +package io.a2a.grpc; + +@com.google.protobuf.Generated +public interface AgentCardSignatureOrBuilder extends + // @@protoc_insertion_point(interface_extends:a2a.v1.AgentCardSignature) + com.google.protobuf.MessageOrBuilder { + + /** + *
+   * The protected JWS header for the signature. This is always a
+   * base64url-encoded JSON object. Required.
+   * 
+ * + * string protected = 1 [(.google.api.field_behavior) = REQUIRED]; + * @return The protected. + */ + java.lang.String getProtected(); + /** + *
+   * The protected JWS header for the signature. This is always a
+   * base64url-encoded JSON object. Required.
+   * 
+ * + * string protected = 1 [(.google.api.field_behavior) = REQUIRED]; + * @return The bytes for protected. + */ + com.google.protobuf.ByteString + getProtectedBytes(); + + /** + *
+   * The computed signature, base64url-encoded. Required.
+   * 
+ * + * string signature = 2 [(.google.api.field_behavior) = REQUIRED]; + * @return The signature. + */ + java.lang.String getSignature(); + /** + *
+   * The computed signature, base64url-encoded. Required.
+   * 
+ * + * string signature = 2 [(.google.api.field_behavior) = REQUIRED]; + * @return The bytes for signature. + */ + com.google.protobuf.ByteString + getSignatureBytes(); + + /** + *
+   * The unprotected JWS header values.
+   * 
+ * + * .google.protobuf.Struct header = 3; + * @return Whether the header field is set. + */ + boolean hasHeader(); + /** + *
+   * The unprotected JWS header values.
+   * 
+ * + * .google.protobuf.Struct header = 3; + * @return The header. + */ + com.google.protobuf.Struct getHeader(); + /** + *
+   * The unprotected JWS header values.
+   * 
+ * + * .google.protobuf.Struct header = 3; + */ + com.google.protobuf.StructOrBuilder getHeaderOrBuilder(); +} diff --git a/spec-grpc/src/main/java/io/a2a/grpc/AgentSkill.java b/spec-grpc/src/main/java/io/a2a/grpc/AgentSkill.java index 1d6fed46c..794c3db57 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/AgentSkill.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/AgentSkill.java @@ -47,6 +47,7 @@ private AgentSkill() { com.google.protobuf.LazyStringArrayList.emptyList(); outputModes_ = com.google.protobuf.LazyStringArrayList.emptyList(); + security_ = java.util.Collections.emptyList(); } public static final com.google.protobuf.Descriptors.Descriptor @@ -433,6 +434,87 @@ public java.lang.String getOutputModes(int index) { return outputModes_.getByteString(index); } + public static final int SECURITY_FIELD_NUMBER = 8; + @SuppressWarnings("serial") + private java.util.List security_; + /** + *
+   * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+   * Security schemes necessary for the agent to leverage this skill.
+   * As in the overall AgentCard.security, this list represents a logical OR of
+   * security requirement objects. Each object is a set of security schemes
+   * that must be used together (a logical AND).
+   * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + @java.lang.Override + public java.util.List getSecurityList() { + return security_; + } + /** + *
+   * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+   * Security schemes necessary for the agent to leverage this skill.
+   * As in the overall AgentCard.security, this list represents a logical OR of
+   * security requirement objects. Each object is a set of security schemes
+   * that must be used together (a logical AND).
+   * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + @java.lang.Override + public java.util.List + getSecurityOrBuilderList() { + return security_; + } + /** + *
+   * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+   * Security schemes necessary for the agent to leverage this skill.
+   * As in the overall AgentCard.security, this list represents a logical OR of
+   * security requirement objects. Each object is a set of security schemes
+   * that must be used together (a logical AND).
+   * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + @java.lang.Override + public int getSecurityCount() { + return security_.size(); + } + /** + *
+   * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+   * Security schemes necessary for the agent to leverage this skill.
+   * As in the overall AgentCard.security, this list represents a logical OR of
+   * security requirement objects. Each object is a set of security schemes
+   * that must be used together (a logical AND).
+   * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + @java.lang.Override + public io.a2a.grpc.Security getSecurity(int index) { + return security_.get(index); + } + /** + *
+   * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+   * Security schemes necessary for the agent to leverage this skill.
+   * As in the overall AgentCard.security, this list represents a logical OR of
+   * security requirement objects. Each object is a set of security schemes
+   * that must be used together (a logical AND).
+   * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + @java.lang.Override + public io.a2a.grpc.SecurityOrBuilder getSecurityOrBuilder( + int index) { + return security_.get(index); + } + private byte memoizedIsInitialized = -1; @java.lang.Override public final boolean isInitialized() { @@ -468,6 +550,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) for (int i = 0; i < outputModes_.size(); i++) { com.google.protobuf.GeneratedMessage.writeString(output, 7, outputModes_.getRaw(i)); } + for (int i = 0; i < security_.size(); i++) { + output.writeMessage(8, security_.get(i)); + } getUnknownFields().writeTo(output); } @@ -518,6 +603,10 @@ public int getSerializedSize() { size += dataSize; size += 1 * getOutputModesList().size(); } + for (int i = 0; i < security_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(8, security_.get(i)); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -547,6 +636,8 @@ public boolean equals(final java.lang.Object obj) { .equals(other.getInputModesList())) return false; if (!getOutputModesList() .equals(other.getOutputModesList())) return false; + if (!getSecurityList() + .equals(other.getSecurityList())) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -580,6 +671,10 @@ public int hashCode() { hash = (37 * hash) + OUTPUT_MODES_FIELD_NUMBER; hash = (53 * hash) + getOutputModesList().hashCode(); } + if (getSecurityCount() > 0) { + hash = (37 * hash) + SECURITY_FIELD_NUMBER; + hash = (53 * hash) + getSecurityList().hashCode(); + } hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -730,6 +825,13 @@ public Builder clear() { com.google.protobuf.LazyStringArrayList.emptyList(); outputModes_ = com.google.protobuf.LazyStringArrayList.emptyList(); + if (securityBuilder_ == null) { + security_ = java.util.Collections.emptyList(); + } else { + security_ = null; + securityBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000080); return this; } @@ -756,11 +858,24 @@ public io.a2a.grpc.AgentSkill build() { @java.lang.Override public io.a2a.grpc.AgentSkill buildPartial() { io.a2a.grpc.AgentSkill result = new io.a2a.grpc.AgentSkill(this); + buildPartialRepeatedFields(result); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } + private void buildPartialRepeatedFields(io.a2a.grpc.AgentSkill result) { + if (securityBuilder_ == null) { + if (((bitField0_ & 0x00000080) != 0)) { + security_ = java.util.Collections.unmodifiableList(security_); + bitField0_ = (bitField0_ & ~0x00000080); + } + result.security_ = security_; + } else { + result.security_ = securityBuilder_.build(); + } + } + private void buildPartial0(io.a2a.grpc.AgentSkill result) { int from_bitField0_ = bitField0_; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -857,6 +972,32 @@ public Builder mergeFrom(io.a2a.grpc.AgentSkill other) { } onChanged(); } + if (securityBuilder_ == null) { + if (!other.security_.isEmpty()) { + if (security_.isEmpty()) { + security_ = other.security_; + bitField0_ = (bitField0_ & ~0x00000080); + } else { + ensureSecurityIsMutable(); + security_.addAll(other.security_); + } + onChanged(); + } + } else { + if (!other.security_.isEmpty()) { + if (securityBuilder_.isEmpty()) { + securityBuilder_.dispose(); + securityBuilder_ = null; + security_ = other.security_; + bitField0_ = (bitField0_ & ~0x00000080); + securityBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + internalGetSecurityFieldBuilder() : null; + } else { + securityBuilder_.addAllMessages(other.security_); + } + } + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -922,6 +1063,19 @@ public Builder mergeFrom( outputModes_.add(s); break; } // case 58 + case 66: { + io.a2a.grpc.Security m = + input.readMessage( + io.a2a.grpc.Security.parser(), + extensionRegistry); + if (securityBuilder_ == null) { + ensureSecurityIsMutable(); + security_.add(m); + } else { + securityBuilder_.addMessage(m); + } + break; + } // case 66 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -1844,6 +1998,390 @@ public Builder addOutputModesBytes( return this; } + private java.util.List security_ = + java.util.Collections.emptyList(); + private void ensureSecurityIsMutable() { + if (!((bitField0_ & 0x00000080) != 0)) { + security_ = new java.util.ArrayList(security_); + bitField0_ |= 0x00000080; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + io.a2a.grpc.Security, io.a2a.grpc.Security.Builder, io.a2a.grpc.SecurityOrBuilder> securityBuilder_; + + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public java.util.List getSecurityList() { + if (securityBuilder_ == null) { + return java.util.Collections.unmodifiableList(security_); + } else { + return securityBuilder_.getMessageList(); + } + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public int getSecurityCount() { + if (securityBuilder_ == null) { + return security_.size(); + } else { + return securityBuilder_.getCount(); + } + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public io.a2a.grpc.Security getSecurity(int index) { + if (securityBuilder_ == null) { + return security_.get(index); + } else { + return securityBuilder_.getMessage(index); + } + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public Builder setSecurity( + int index, io.a2a.grpc.Security value) { + if (securityBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSecurityIsMutable(); + security_.set(index, value); + onChanged(); + } else { + securityBuilder_.setMessage(index, value); + } + return this; + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public Builder setSecurity( + int index, io.a2a.grpc.Security.Builder builderForValue) { + if (securityBuilder_ == null) { + ensureSecurityIsMutable(); + security_.set(index, builderForValue.build()); + onChanged(); + } else { + securityBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public Builder addSecurity(io.a2a.grpc.Security value) { + if (securityBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSecurityIsMutable(); + security_.add(value); + onChanged(); + } else { + securityBuilder_.addMessage(value); + } + return this; + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public Builder addSecurity( + int index, io.a2a.grpc.Security value) { + if (securityBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSecurityIsMutable(); + security_.add(index, value); + onChanged(); + } else { + securityBuilder_.addMessage(index, value); + } + return this; + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public Builder addSecurity( + io.a2a.grpc.Security.Builder builderForValue) { + if (securityBuilder_ == null) { + ensureSecurityIsMutable(); + security_.add(builderForValue.build()); + onChanged(); + } else { + securityBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public Builder addSecurity( + int index, io.a2a.grpc.Security.Builder builderForValue) { + if (securityBuilder_ == null) { + ensureSecurityIsMutable(); + security_.add(index, builderForValue.build()); + onChanged(); + } else { + securityBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public Builder addAllSecurity( + java.lang.Iterable values) { + if (securityBuilder_ == null) { + ensureSecurityIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, security_); + onChanged(); + } else { + securityBuilder_.addAllMessages(values); + } + return this; + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public Builder clearSecurity() { + if (securityBuilder_ == null) { + security_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000080); + onChanged(); + } else { + securityBuilder_.clear(); + } + return this; + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public Builder removeSecurity(int index) { + if (securityBuilder_ == null) { + ensureSecurityIsMutable(); + security_.remove(index); + onChanged(); + } else { + securityBuilder_.remove(index); + } + return this; + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public io.a2a.grpc.Security.Builder getSecurityBuilder( + int index) { + return internalGetSecurityFieldBuilder().getBuilder(index); + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public io.a2a.grpc.SecurityOrBuilder getSecurityOrBuilder( + int index) { + if (securityBuilder_ == null) { + return security_.get(index); } else { + return securityBuilder_.getMessageOrBuilder(index); + } + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public java.util.List + getSecurityOrBuilderList() { + if (securityBuilder_ != null) { + return securityBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(security_); + } + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public io.a2a.grpc.Security.Builder addSecurityBuilder() { + return internalGetSecurityFieldBuilder().addBuilder( + io.a2a.grpc.Security.getDefaultInstance()); + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public io.a2a.grpc.Security.Builder addSecurityBuilder( + int index) { + return internalGetSecurityFieldBuilder().addBuilder( + index, io.a2a.grpc.Security.getDefaultInstance()); + } + /** + *
+     * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+     * Security schemes necessary for the agent to leverage this skill.
+     * As in the overall AgentCard.security, this list represents a logical OR of
+     * security requirement objects. Each object is a set of security schemes
+     * that must be used together (a logical AND).
+     * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + public java.util.List + getSecurityBuilderList() { + return internalGetSecurityFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + io.a2a.grpc.Security, io.a2a.grpc.Security.Builder, io.a2a.grpc.SecurityOrBuilder> + internalGetSecurityFieldBuilder() { + if (securityBuilder_ == null) { + securityBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + io.a2a.grpc.Security, io.a2a.grpc.Security.Builder, io.a2a.grpc.SecurityOrBuilder>( + security_, + ((bitField0_ & 0x00000080) != 0), + getParentForChildren(), + isClean()); + security_ = null; + } + return securityBuilder_; + } + // @@protoc_insertion_point(builder_scope:a2a.v1.AgentSkill) } diff --git a/spec-grpc/src/main/java/io/a2a/grpc/AgentSkillOrBuilder.java b/spec-grpc/src/main/java/io/a2a/grpc/AgentSkillOrBuilder.java index d776b3112..88ebf7448 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/AgentSkillOrBuilder.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/AgentSkillOrBuilder.java @@ -251,4 +251,68 @@ public interface AgentSkillOrBuilder extends */ com.google.protobuf.ByteString getOutputModesBytes(int index); + + /** + *
+   * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+   * Security schemes necessary for the agent to leverage this skill.
+   * As in the overall AgentCard.security, this list represents a logical OR of
+   * security requirement objects. Each object is a set of security schemes
+   * that must be used together (a logical AND).
+   * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + java.util.List + getSecurityList(); + /** + *
+   * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+   * Security schemes necessary for the agent to leverage this skill.
+   * As in the overall AgentCard.security, this list represents a logical OR of
+   * security requirement objects. Each object is a set of security schemes
+   * that must be used together (a logical AND).
+   * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + io.a2a.grpc.Security getSecurity(int index); + /** + *
+   * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+   * Security schemes necessary for the agent to leverage this skill.
+   * As in the overall AgentCard.security, this list represents a logical OR of
+   * security requirement objects. Each object is a set of security schemes
+   * that must be used together (a logical AND).
+   * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + int getSecurityCount(); + /** + *
+   * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+   * Security schemes necessary for the agent to leverage this skill.
+   * As in the overall AgentCard.security, this list represents a logical OR of
+   * security requirement objects. Each object is a set of security schemes
+   * that must be used together (a logical AND).
+   * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + java.util.List + getSecurityOrBuilderList(); + /** + *
+   * protolint:disable REPEATED_FIELD_NAMES_PLURALIZED
+   * Security schemes necessary for the agent to leverage this skill.
+   * As in the overall AgentCard.security, this list represents a logical OR of
+   * security requirement objects. Each object is a set of security schemes
+   * that must be used together (a logical AND).
+   * 
+ * + * repeated .a2a.v1.Security security = 8; + */ + io.a2a.grpc.SecurityOrBuilder getSecurityOrBuilder( + int index); } diff --git a/spec-grpc/src/main/java/io/a2a/grpc/MutualTlsSecurityScheme.java b/spec-grpc/src/main/java/io/a2a/grpc/MutualTlsSecurityScheme.java new file mode 100644 index 000000000..87ef07b99 --- /dev/null +++ b/spec-grpc/src/main/java/io/a2a/grpc/MutualTlsSecurityScheme.java @@ -0,0 +1,530 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// NO CHECKED-IN PROTOBUF GENCODE +// source: a2a.proto +// Protobuf Java Version: 4.31.1 + +package io.a2a.grpc; + +/** + * Protobuf type {@code a2a.v1.MutualTlsSecurityScheme} + */ +@com.google.protobuf.Generated +public final class MutualTlsSecurityScheme extends + com.google.protobuf.GeneratedMessage implements + // @@protoc_insertion_point(message_implements:a2a.v1.MutualTlsSecurityScheme) + MutualTlsSecuritySchemeOrBuilder { +private static final long serialVersionUID = 0L; + static { + com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( + com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, + /* major= */ 4, + /* minor= */ 31, + /* patch= */ 1, + /* suffix= */ "", + MutualTlsSecurityScheme.class.getName()); + } + // Use MutualTlsSecurityScheme.newBuilder() to construct. + private MutualTlsSecurityScheme(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + } + private MutualTlsSecurityScheme() { + description_ = ""; + } + + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return io.a2a.grpc.A2A.internal_static_a2a_v1_MutualTlsSecurityScheme_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.a2a.grpc.A2A.internal_static_a2a_v1_MutualTlsSecurityScheme_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.a2a.grpc.MutualTlsSecurityScheme.class, io.a2a.grpc.MutualTlsSecurityScheme.Builder.class); + } + + public static final int DESCRIPTION_FIELD_NUMBER = 1; + @SuppressWarnings("serial") + private volatile java.lang.Object description_ = ""; + /** + *
+   * Description of this security scheme.
+   * 
+ * + * string description = 1; + * @return The description. + */ + @java.lang.Override + public java.lang.String getDescription() { + java.lang.Object ref = description_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + description_ = s; + return s; + } + } + /** + *
+   * Description of this security scheme.
+   * 
+ * + * string description = 1; + * @return The bytes for description. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getDescriptionBytes() { + java.lang.Object ref = description_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + description_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessage.isStringEmpty(description_)) { + com.google.protobuf.GeneratedMessage.writeString(output, 1, description_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessage.isStringEmpty(description_)) { + size += com.google.protobuf.GeneratedMessage.computeStringSize(1, description_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.a2a.grpc.MutualTlsSecurityScheme)) { + return super.equals(obj); + } + io.a2a.grpc.MutualTlsSecurityScheme other = (io.a2a.grpc.MutualTlsSecurityScheme) obj; + + if (!getDescription() + .equals(other.getDescription())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + DESCRIPTION_FIELD_NUMBER; + hash = (53 * hash) + getDescription().hashCode(); + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.a2a.grpc.MutualTlsSecurityScheme parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.a2a.grpc.MutualTlsSecurityScheme parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.a2a.grpc.MutualTlsSecurityScheme parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.a2a.grpc.MutualTlsSecurityScheme parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.a2a.grpc.MutualTlsSecurityScheme parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.a2a.grpc.MutualTlsSecurityScheme parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.a2a.grpc.MutualTlsSecurityScheme parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input); + } + public static io.a2a.grpc.MutualTlsSecurityScheme parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public static io.a2a.grpc.MutualTlsSecurityScheme parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseDelimitedWithIOException(PARSER, input); + } + + public static io.a2a.grpc.MutualTlsSecurityScheme parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.a2a.grpc.MutualTlsSecurityScheme parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input); + } + public static io.a2a.grpc.MutualTlsSecurityScheme parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.a2a.grpc.MutualTlsSecurityScheme prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code a2a.v1.MutualTlsSecurityScheme} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder implements + // @@protoc_insertion_point(builder_implements:a2a.v1.MutualTlsSecurityScheme) + io.a2a.grpc.MutualTlsSecuritySchemeOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return io.a2a.grpc.A2A.internal_static_a2a_v1_MutualTlsSecurityScheme_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.a2a.grpc.A2A.internal_static_a2a_v1_MutualTlsSecurityScheme_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.a2a.grpc.MutualTlsSecurityScheme.class, io.a2a.grpc.MutualTlsSecurityScheme.Builder.class); + } + + // Construct using io.a2a.grpc.MutualTlsSecurityScheme.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + description_ = ""; + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return io.a2a.grpc.A2A.internal_static_a2a_v1_MutualTlsSecurityScheme_descriptor; + } + + @java.lang.Override + public io.a2a.grpc.MutualTlsSecurityScheme getDefaultInstanceForType() { + return io.a2a.grpc.MutualTlsSecurityScheme.getDefaultInstance(); + } + + @java.lang.Override + public io.a2a.grpc.MutualTlsSecurityScheme build() { + io.a2a.grpc.MutualTlsSecurityScheme result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.a2a.grpc.MutualTlsSecurityScheme buildPartial() { + io.a2a.grpc.MutualTlsSecurityScheme result = new io.a2a.grpc.MutualTlsSecurityScheme(this); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartial0(io.a2a.grpc.MutualTlsSecurityScheme result) { + int from_bitField0_ = bitField0_; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.description_ = description_; + } + } + + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof io.a2a.grpc.MutualTlsSecurityScheme) { + return mergeFrom((io.a2a.grpc.MutualTlsSecurityScheme)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.a2a.grpc.MutualTlsSecurityScheme other) { + if (other == io.a2a.grpc.MutualTlsSecurityScheme.getDefaultInstance()) return this; + if (!other.getDescription().isEmpty()) { + description_ = other.description_; + bitField0_ |= 0x00000001; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + description_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000001; + break; + } // case 10 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private java.lang.Object description_ = ""; + /** + *
+     * Description of this security scheme.
+     * 
+ * + * string description = 1; + * @return The description. + */ + public java.lang.String getDescription() { + java.lang.Object ref = description_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + description_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+     * Description of this security scheme.
+     * 
+ * + * string description = 1; + * @return The bytes for description. + */ + public com.google.protobuf.ByteString + getDescriptionBytes() { + java.lang.Object ref = description_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + description_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+     * Description of this security scheme.
+     * 
+ * + * string description = 1; + * @param value The description to set. + * @return This builder for chaining. + */ + public Builder setDescription( + java.lang.String value) { + if (value == null) { throw new NullPointerException(); } + description_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + *
+     * Description of this security scheme.
+     * 
+ * + * string description = 1; + * @return This builder for chaining. + */ + public Builder clearDescription() { + description_ = getDefaultInstance().getDescription(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + *
+     * Description of this security scheme.
+     * 
+ * + * string description = 1; + * @param value The bytes for description to set. + * @return This builder for chaining. + */ + public Builder setDescriptionBytes( + com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + checkByteStringIsUtf8(value); + description_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:a2a.v1.MutualTlsSecurityScheme) + } + + // @@protoc_insertion_point(class_scope:a2a.v1.MutualTlsSecurityScheme) + private static final io.a2a.grpc.MutualTlsSecurityScheme DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.a2a.grpc.MutualTlsSecurityScheme(); + } + + public static io.a2a.grpc.MutualTlsSecurityScheme getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public MutualTlsSecurityScheme parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.a2a.grpc.MutualTlsSecurityScheme getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/spec-grpc/src/main/java/io/a2a/grpc/MutualTlsSecuritySchemeOrBuilder.java b/spec-grpc/src/main/java/io/a2a/grpc/MutualTlsSecuritySchemeOrBuilder.java new file mode 100644 index 000000000..a18e1311a --- /dev/null +++ b/spec-grpc/src/main/java/io/a2a/grpc/MutualTlsSecuritySchemeOrBuilder.java @@ -0,0 +1,32 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// NO CHECKED-IN PROTOBUF GENCODE +// source: a2a.proto +// Protobuf Java Version: 4.31.1 + +package io.a2a.grpc; + +@com.google.protobuf.Generated +public interface MutualTlsSecuritySchemeOrBuilder extends + // @@protoc_insertion_point(interface_extends:a2a.v1.MutualTlsSecurityScheme) + com.google.protobuf.MessageOrBuilder { + + /** + *
+   * Description of this security scheme.
+   * 
+ * + * string description = 1; + * @return The description. + */ + java.lang.String getDescription(); + /** + *
+   * Description of this security scheme.
+   * 
+ * + * string description = 1; + * @return The bytes for description. + */ + com.google.protobuf.ByteString + getDescriptionBytes(); +} diff --git a/spec-grpc/src/main/java/io/a2a/grpc/OAuth2SecurityScheme.java b/spec-grpc/src/main/java/io/a2a/grpc/OAuth2SecurityScheme.java index 11065d682..9de35587e 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/OAuth2SecurityScheme.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/OAuth2SecurityScheme.java @@ -29,6 +29,7 @@ private OAuth2SecurityScheme(com.google.protobuf.GeneratedMessage.Builder bui } private OAuth2SecurityScheme() { description_ = ""; + oauth2MetadataUrl_ = ""; } public static final com.google.protobuf.Descriptors.Descriptor @@ -130,6 +131,55 @@ public io.a2a.grpc.OAuthFlowsOrBuilder getFlowsOrBuilder() { return flows_ == null ? io.a2a.grpc.OAuthFlows.getDefaultInstance() : flows_; } + public static final int OAUTH2_METADATA_URL_FIELD_NUMBER = 3; + @SuppressWarnings("serial") + private volatile java.lang.Object oauth2MetadataUrl_ = ""; + /** + *
+   * URL to the oauth2 authorization server metadata
+   * [RFC8414](https://datatracker.ietf.org/doc/html/rfc8414). TLS is required.
+   * 
+ * + * string oauth2_metadata_url = 3; + * @return The oauth2MetadataUrl. + */ + @java.lang.Override + public java.lang.String getOauth2MetadataUrl() { + java.lang.Object ref = oauth2MetadataUrl_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + oauth2MetadataUrl_ = s; + return s; + } + } + /** + *
+   * URL to the oauth2 authorization server metadata
+   * [RFC8414](https://datatracker.ietf.org/doc/html/rfc8414). TLS is required.
+   * 
+ * + * string oauth2_metadata_url = 3; + * @return The bytes for oauth2MetadataUrl. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getOauth2MetadataUrlBytes() { + java.lang.Object ref = oauth2MetadataUrl_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + oauth2MetadataUrl_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + private byte memoizedIsInitialized = -1; @java.lang.Override public final boolean isInitialized() { @@ -150,6 +200,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (((bitField0_ & 0x00000001) != 0)) { output.writeMessage(2, getFlows()); } + if (!com.google.protobuf.GeneratedMessage.isStringEmpty(oauth2MetadataUrl_)) { + com.google.protobuf.GeneratedMessage.writeString(output, 3, oauth2MetadataUrl_); + } getUnknownFields().writeTo(output); } @@ -166,6 +219,9 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeMessageSize(2, getFlows()); } + if (!com.google.protobuf.GeneratedMessage.isStringEmpty(oauth2MetadataUrl_)) { + size += com.google.protobuf.GeneratedMessage.computeStringSize(3, oauth2MetadataUrl_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -188,6 +244,8 @@ public boolean equals(final java.lang.Object obj) { if (!getFlows() .equals(other.getFlows())) return false; } + if (!getOauth2MetadataUrl() + .equals(other.getOauth2MetadataUrl())) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -205,6 +263,8 @@ public int hashCode() { hash = (37 * hash) + FLOWS_FIELD_NUMBER; hash = (53 * hash) + getFlows().hashCode(); } + hash = (37 * hash) + OAUTH2_METADATA_URL_FIELD_NUMBER; + hash = (53 * hash) + getOauth2MetadataUrl().hashCode(); hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -348,6 +408,7 @@ public Builder clear() { flowsBuilder_.dispose(); flowsBuilder_ = null; } + oauth2MetadataUrl_ = ""; return this; } @@ -391,6 +452,9 @@ private void buildPartial0(io.a2a.grpc.OAuth2SecurityScheme result) { : flowsBuilder_.build(); to_bitField0_ |= 0x00000001; } + if (((from_bitField0_ & 0x00000004) != 0)) { + result.oauth2MetadataUrl_ = oauth2MetadataUrl_; + } result.bitField0_ |= to_bitField0_; } @@ -414,6 +478,11 @@ public Builder mergeFrom(io.a2a.grpc.OAuth2SecurityScheme other) { if (other.hasFlows()) { mergeFlows(other.getFlows()); } + if (!other.getOauth2MetadataUrl().isEmpty()) { + oauth2MetadataUrl_ = other.oauth2MetadataUrl_; + bitField0_ |= 0x00000004; + onChanged(); + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -452,6 +521,11 @@ public Builder mergeFrom( bitField0_ |= 0x00000002; break; } // case 18 + case 26: { + oauth2MetadataUrl_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000004; + break; + } // case 26 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -718,6 +792,103 @@ public io.a2a.grpc.OAuthFlowsOrBuilder getFlowsOrBuilder() { return flowsBuilder_; } + private java.lang.Object oauth2MetadataUrl_ = ""; + /** + *
+     * URL to the oauth2 authorization server metadata
+     * [RFC8414](https://datatracker.ietf.org/doc/html/rfc8414). TLS is required.
+     * 
+ * + * string oauth2_metadata_url = 3; + * @return The oauth2MetadataUrl. + */ + public java.lang.String getOauth2MetadataUrl() { + java.lang.Object ref = oauth2MetadataUrl_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + oauth2MetadataUrl_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+     * URL to the oauth2 authorization server metadata
+     * [RFC8414](https://datatracker.ietf.org/doc/html/rfc8414). TLS is required.
+     * 
+ * + * string oauth2_metadata_url = 3; + * @return The bytes for oauth2MetadataUrl. + */ + public com.google.protobuf.ByteString + getOauth2MetadataUrlBytes() { + java.lang.Object ref = oauth2MetadataUrl_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + oauth2MetadataUrl_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+     * URL to the oauth2 authorization server metadata
+     * [RFC8414](https://datatracker.ietf.org/doc/html/rfc8414). TLS is required.
+     * 
+ * + * string oauth2_metadata_url = 3; + * @param value The oauth2MetadataUrl to set. + * @return This builder for chaining. + */ + public Builder setOauth2MetadataUrl( + java.lang.String value) { + if (value == null) { throw new NullPointerException(); } + oauth2MetadataUrl_ = value; + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + *
+     * URL to the oauth2 authorization server metadata
+     * [RFC8414](https://datatracker.ietf.org/doc/html/rfc8414). TLS is required.
+     * 
+ * + * string oauth2_metadata_url = 3; + * @return This builder for chaining. + */ + public Builder clearOauth2MetadataUrl() { + oauth2MetadataUrl_ = getDefaultInstance().getOauth2MetadataUrl(); + bitField0_ = (bitField0_ & ~0x00000004); + onChanged(); + return this; + } + /** + *
+     * URL to the oauth2 authorization server metadata
+     * [RFC8414](https://datatracker.ietf.org/doc/html/rfc8414). TLS is required.
+     * 
+ * + * string oauth2_metadata_url = 3; + * @param value The bytes for oauth2MetadataUrl to set. + * @return This builder for chaining. + */ + public Builder setOauth2MetadataUrlBytes( + com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + checkByteStringIsUtf8(value); + oauth2MetadataUrl_ = value; + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + // @@protoc_insertion_point(builder_scope:a2a.v1.OAuth2SecurityScheme) } diff --git a/spec-grpc/src/main/java/io/a2a/grpc/OAuth2SecuritySchemeOrBuilder.java b/spec-grpc/src/main/java/io/a2a/grpc/OAuth2SecuritySchemeOrBuilder.java index 76620c1ba..84c35ce0c 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/OAuth2SecuritySchemeOrBuilder.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/OAuth2SecuritySchemeOrBuilder.java @@ -56,4 +56,26 @@ public interface OAuth2SecuritySchemeOrBuilder extends * .a2a.v1.OAuthFlows flows = 2; */ io.a2a.grpc.OAuthFlowsOrBuilder getFlowsOrBuilder(); + + /** + *
+   * URL to the oauth2 authorization server metadata
+   * [RFC8414](https://datatracker.ietf.org/doc/html/rfc8414). TLS is required.
+   * 
+ * + * string oauth2_metadata_url = 3; + * @return The oauth2MetadataUrl. + */ + java.lang.String getOauth2MetadataUrl(); + /** + *
+   * URL to the oauth2 authorization server metadata
+   * [RFC8414](https://datatracker.ietf.org/doc/html/rfc8414). TLS is required.
+   * 
+ * + * string oauth2_metadata_url = 3; + * @return The bytes for oauth2MetadataUrl. + */ + com.google.protobuf.ByteString + getOauth2MetadataUrlBytes(); } diff --git a/spec-grpc/src/main/java/io/a2a/grpc/SecurityScheme.java b/spec-grpc/src/main/java/io/a2a/grpc/SecurityScheme.java index b6726d097..90bc8672d 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/SecurityScheme.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/SecurityScheme.java @@ -53,6 +53,7 @@ public enum SchemeCase HTTP_AUTH_SECURITY_SCHEME(2), OAUTH2_SECURITY_SCHEME(3), OPEN_ID_CONNECT_SECURITY_SCHEME(4), + MTLS_SECURITY_SCHEME(5), SCHEME_NOT_SET(0); private final int value; private SchemeCase(int value) { @@ -74,6 +75,7 @@ public static SchemeCase forNumber(int value) { case 2: return HTTP_AUTH_SECURITY_SCHEME; case 3: return OAUTH2_SECURITY_SCHEME; case 4: return OPEN_ID_CONNECT_SECURITY_SCHEME; + case 5: return MTLS_SECURITY_SCHEME; case 0: return SCHEME_NOT_SET; default: return null; } @@ -213,6 +215,37 @@ public io.a2a.grpc.OpenIdConnectSecuritySchemeOrBuilder getOpenIdConnectSecurity return io.a2a.grpc.OpenIdConnectSecurityScheme.getDefaultInstance(); } + public static final int MTLS_SECURITY_SCHEME_FIELD_NUMBER = 5; + /** + * .a2a.v1.MutualTlsSecurityScheme mtls_security_scheme = 5; + * @return Whether the mtlsSecurityScheme field is set. + */ + @java.lang.Override + public boolean hasMtlsSecurityScheme() { + return schemeCase_ == 5; + } + /** + * .a2a.v1.MutualTlsSecurityScheme mtls_security_scheme = 5; + * @return The mtlsSecurityScheme. + */ + @java.lang.Override + public io.a2a.grpc.MutualTlsSecurityScheme getMtlsSecurityScheme() { + if (schemeCase_ == 5) { + return (io.a2a.grpc.MutualTlsSecurityScheme) scheme_; + } + return io.a2a.grpc.MutualTlsSecurityScheme.getDefaultInstance(); + } + /** + * .a2a.v1.MutualTlsSecurityScheme mtls_security_scheme = 5; + */ + @java.lang.Override + public io.a2a.grpc.MutualTlsSecuritySchemeOrBuilder getMtlsSecuritySchemeOrBuilder() { + if (schemeCase_ == 5) { + return (io.a2a.grpc.MutualTlsSecurityScheme) scheme_; + } + return io.a2a.grpc.MutualTlsSecurityScheme.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; @java.lang.Override public final boolean isInitialized() { @@ -239,6 +272,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (schemeCase_ == 4) { output.writeMessage(4, (io.a2a.grpc.OpenIdConnectSecurityScheme) scheme_); } + if (schemeCase_ == 5) { + output.writeMessage(5, (io.a2a.grpc.MutualTlsSecurityScheme) scheme_); + } getUnknownFields().writeTo(output); } @@ -264,6 +300,10 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeMessageSize(4, (io.a2a.grpc.OpenIdConnectSecurityScheme) scheme_); } + if (schemeCase_ == 5) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(5, (io.a2a.grpc.MutualTlsSecurityScheme) scheme_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -297,6 +337,10 @@ public boolean equals(final java.lang.Object obj) { if (!getOpenIdConnectSecurityScheme() .equals(other.getOpenIdConnectSecurityScheme())) return false; break; + case 5: + if (!getMtlsSecurityScheme() + .equals(other.getMtlsSecurityScheme())) return false; + break; case 0: default: } @@ -328,6 +372,10 @@ public int hashCode() { hash = (37 * hash) + OPEN_ID_CONNECT_SECURITY_SCHEME_FIELD_NUMBER; hash = (53 * hash) + getOpenIdConnectSecurityScheme().hashCode(); break; + case 5: + hash = (37 * hash) + MTLS_SECURITY_SCHEME_FIELD_NUMBER; + hash = (53 * hash) + getMtlsSecurityScheme().hashCode(); + break; case 0: default: } @@ -474,6 +522,9 @@ public Builder clear() { if (openIdConnectSecuritySchemeBuilder_ != null) { openIdConnectSecuritySchemeBuilder_.clear(); } + if (mtlsSecuritySchemeBuilder_ != null) { + mtlsSecuritySchemeBuilder_.clear(); + } schemeCase_ = 0; scheme_ = null; return this; @@ -531,6 +582,10 @@ private void buildPartialOneofs(io.a2a.grpc.SecurityScheme result) { openIdConnectSecuritySchemeBuilder_ != null) { result.scheme_ = openIdConnectSecuritySchemeBuilder_.build(); } + if (schemeCase_ == 5 && + mtlsSecuritySchemeBuilder_ != null) { + result.scheme_ = mtlsSecuritySchemeBuilder_.build(); + } } @java.lang.Override @@ -562,6 +617,10 @@ public Builder mergeFrom(io.a2a.grpc.SecurityScheme other) { mergeOpenIdConnectSecurityScheme(other.getOpenIdConnectSecurityScheme()); break; } + case MTLS_SECURITY_SCHEME: { + mergeMtlsSecurityScheme(other.getMtlsSecurityScheme()); + break; + } case SCHEME_NOT_SET: { break; } @@ -620,6 +679,13 @@ public Builder mergeFrom( schemeCase_ = 4; break; } // case 34 + case 42: { + input.readMessage( + internalGetMtlsSecuritySchemeFieldBuilder().getBuilder(), + extensionRegistry); + schemeCase_ = 5; + break; + } // case 42 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -1220,6 +1286,148 @@ public io.a2a.grpc.OpenIdConnectSecuritySchemeOrBuilder getOpenIdConnectSecurity return openIdConnectSecuritySchemeBuilder_; } + private com.google.protobuf.SingleFieldBuilder< + io.a2a.grpc.MutualTlsSecurityScheme, io.a2a.grpc.MutualTlsSecurityScheme.Builder, io.a2a.grpc.MutualTlsSecuritySchemeOrBuilder> mtlsSecuritySchemeBuilder_; + /** + * .a2a.v1.MutualTlsSecurityScheme mtls_security_scheme = 5; + * @return Whether the mtlsSecurityScheme field is set. + */ + @java.lang.Override + public boolean hasMtlsSecurityScheme() { + return schemeCase_ == 5; + } + /** + * .a2a.v1.MutualTlsSecurityScheme mtls_security_scheme = 5; + * @return The mtlsSecurityScheme. + */ + @java.lang.Override + public io.a2a.grpc.MutualTlsSecurityScheme getMtlsSecurityScheme() { + if (mtlsSecuritySchemeBuilder_ == null) { + if (schemeCase_ == 5) { + return (io.a2a.grpc.MutualTlsSecurityScheme) scheme_; + } + return io.a2a.grpc.MutualTlsSecurityScheme.getDefaultInstance(); + } else { + if (schemeCase_ == 5) { + return mtlsSecuritySchemeBuilder_.getMessage(); + } + return io.a2a.grpc.MutualTlsSecurityScheme.getDefaultInstance(); + } + } + /** + * .a2a.v1.MutualTlsSecurityScheme mtls_security_scheme = 5; + */ + public Builder setMtlsSecurityScheme(io.a2a.grpc.MutualTlsSecurityScheme value) { + if (mtlsSecuritySchemeBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + scheme_ = value; + onChanged(); + } else { + mtlsSecuritySchemeBuilder_.setMessage(value); + } + schemeCase_ = 5; + return this; + } + /** + * .a2a.v1.MutualTlsSecurityScheme mtls_security_scheme = 5; + */ + public Builder setMtlsSecurityScheme( + io.a2a.grpc.MutualTlsSecurityScheme.Builder builderForValue) { + if (mtlsSecuritySchemeBuilder_ == null) { + scheme_ = builderForValue.build(); + onChanged(); + } else { + mtlsSecuritySchemeBuilder_.setMessage(builderForValue.build()); + } + schemeCase_ = 5; + return this; + } + /** + * .a2a.v1.MutualTlsSecurityScheme mtls_security_scheme = 5; + */ + public Builder mergeMtlsSecurityScheme(io.a2a.grpc.MutualTlsSecurityScheme value) { + if (mtlsSecuritySchemeBuilder_ == null) { + if (schemeCase_ == 5 && + scheme_ != io.a2a.grpc.MutualTlsSecurityScheme.getDefaultInstance()) { + scheme_ = io.a2a.grpc.MutualTlsSecurityScheme.newBuilder((io.a2a.grpc.MutualTlsSecurityScheme) scheme_) + .mergeFrom(value).buildPartial(); + } else { + scheme_ = value; + } + onChanged(); + } else { + if (schemeCase_ == 5) { + mtlsSecuritySchemeBuilder_.mergeFrom(value); + } else { + mtlsSecuritySchemeBuilder_.setMessage(value); + } + } + schemeCase_ = 5; + return this; + } + /** + * .a2a.v1.MutualTlsSecurityScheme mtls_security_scheme = 5; + */ + public Builder clearMtlsSecurityScheme() { + if (mtlsSecuritySchemeBuilder_ == null) { + if (schemeCase_ == 5) { + schemeCase_ = 0; + scheme_ = null; + onChanged(); + } + } else { + if (schemeCase_ == 5) { + schemeCase_ = 0; + scheme_ = null; + } + mtlsSecuritySchemeBuilder_.clear(); + } + return this; + } + /** + * .a2a.v1.MutualTlsSecurityScheme mtls_security_scheme = 5; + */ + public io.a2a.grpc.MutualTlsSecurityScheme.Builder getMtlsSecuritySchemeBuilder() { + return internalGetMtlsSecuritySchemeFieldBuilder().getBuilder(); + } + /** + * .a2a.v1.MutualTlsSecurityScheme mtls_security_scheme = 5; + */ + @java.lang.Override + public io.a2a.grpc.MutualTlsSecuritySchemeOrBuilder getMtlsSecuritySchemeOrBuilder() { + if ((schemeCase_ == 5) && (mtlsSecuritySchemeBuilder_ != null)) { + return mtlsSecuritySchemeBuilder_.getMessageOrBuilder(); + } else { + if (schemeCase_ == 5) { + return (io.a2a.grpc.MutualTlsSecurityScheme) scheme_; + } + return io.a2a.grpc.MutualTlsSecurityScheme.getDefaultInstance(); + } + } + /** + * .a2a.v1.MutualTlsSecurityScheme mtls_security_scheme = 5; + */ + private com.google.protobuf.SingleFieldBuilder< + io.a2a.grpc.MutualTlsSecurityScheme, io.a2a.grpc.MutualTlsSecurityScheme.Builder, io.a2a.grpc.MutualTlsSecuritySchemeOrBuilder> + internalGetMtlsSecuritySchemeFieldBuilder() { + if (mtlsSecuritySchemeBuilder_ == null) { + if (!(schemeCase_ == 5)) { + scheme_ = io.a2a.grpc.MutualTlsSecurityScheme.getDefaultInstance(); + } + mtlsSecuritySchemeBuilder_ = new com.google.protobuf.SingleFieldBuilder< + io.a2a.grpc.MutualTlsSecurityScheme, io.a2a.grpc.MutualTlsSecurityScheme.Builder, io.a2a.grpc.MutualTlsSecuritySchemeOrBuilder>( + (io.a2a.grpc.MutualTlsSecurityScheme) scheme_, + getParentForChildren(), + isClean()); + scheme_ = null; + } + schemeCase_ = 5; + onChanged(); + return mtlsSecuritySchemeBuilder_; + } + // @@protoc_insertion_point(builder_scope:a2a.v1.SecurityScheme) } diff --git a/spec-grpc/src/main/java/io/a2a/grpc/SecuritySchemeOrBuilder.java b/spec-grpc/src/main/java/io/a2a/grpc/SecuritySchemeOrBuilder.java index b79be8faf..83a6c0f00 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/SecuritySchemeOrBuilder.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/SecuritySchemeOrBuilder.java @@ -70,5 +70,20 @@ public interface SecuritySchemeOrBuilder extends */ io.a2a.grpc.OpenIdConnectSecuritySchemeOrBuilder getOpenIdConnectSecuritySchemeOrBuilder(); + /** + * .a2a.v1.MutualTlsSecurityScheme mtls_security_scheme = 5; + * @return Whether the mtlsSecurityScheme field is set. + */ + boolean hasMtlsSecurityScheme(); + /** + * .a2a.v1.MutualTlsSecurityScheme mtls_security_scheme = 5; + * @return The mtlsSecurityScheme. + */ + io.a2a.grpc.MutualTlsSecurityScheme getMtlsSecurityScheme(); + /** + * .a2a.v1.MutualTlsSecurityScheme mtls_security_scheme = 5; + */ + io.a2a.grpc.MutualTlsSecuritySchemeOrBuilder getMtlsSecuritySchemeOrBuilder(); + io.a2a.grpc.SecurityScheme.SchemeCase getSchemeCase(); } diff --git a/spec-grpc/src/main/java/io/a2a/grpc/SendMessageRequest.java b/spec-grpc/src/main/java/io/a2a/grpc/SendMessageRequest.java index 53e563640..8882b6d6a 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/SendMessageRequest.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/SendMessageRequest.java @@ -51,7 +51,7 @@ private SendMessageRequest() { public static final int REQUEST_FIELD_NUMBER = 1; private io.a2a.grpc.Message request_; /** - * .a2a.v1.Message request = 1 [(.google.api.field_behavior) = REQUIRED]; + * .a2a.v1.Message request = 1 [json_name = "message", (.google.api.field_behavior) = REQUIRED]; * @return Whether the request field is set. */ @java.lang.Override @@ -59,7 +59,7 @@ public boolean hasRequest() { return ((bitField0_ & 0x00000001) != 0); } /** - * .a2a.v1.Message request = 1 [(.google.api.field_behavior) = REQUIRED]; + * .a2a.v1.Message request = 1 [json_name = "message", (.google.api.field_behavior) = REQUIRED]; * @return The request. */ @java.lang.Override @@ -67,7 +67,7 @@ public io.a2a.grpc.Message getRequest() { return request_ == null ? io.a2a.grpc.Message.getDefaultInstance() : request_; } /** - * .a2a.v1.Message request = 1 [(.google.api.field_behavior) = REQUIRED]; + * .a2a.v1.Message request = 1 [json_name = "message", (.google.api.field_behavior) = REQUIRED]; */ @java.lang.Override public io.a2a.grpc.MessageOrBuilder getRequestOrBuilder() { @@ -525,14 +525,14 @@ public Builder mergeFrom( private com.google.protobuf.SingleFieldBuilder< io.a2a.grpc.Message, io.a2a.grpc.Message.Builder, io.a2a.grpc.MessageOrBuilder> requestBuilder_; /** - * .a2a.v1.Message request = 1 [(.google.api.field_behavior) = REQUIRED]; + * .a2a.v1.Message request = 1 [json_name = "message", (.google.api.field_behavior) = REQUIRED]; * @return Whether the request field is set. */ public boolean hasRequest() { return ((bitField0_ & 0x00000001) != 0); } /** - * .a2a.v1.Message request = 1 [(.google.api.field_behavior) = REQUIRED]; + * .a2a.v1.Message request = 1 [json_name = "message", (.google.api.field_behavior) = REQUIRED]; * @return The request. */ public io.a2a.grpc.Message getRequest() { @@ -543,7 +543,7 @@ public io.a2a.grpc.Message getRequest() { } } /** - * .a2a.v1.Message request = 1 [(.google.api.field_behavior) = REQUIRED]; + * .a2a.v1.Message request = 1 [json_name = "message", (.google.api.field_behavior) = REQUIRED]; */ public Builder setRequest(io.a2a.grpc.Message value) { if (requestBuilder_ == null) { @@ -559,7 +559,7 @@ public Builder setRequest(io.a2a.grpc.Message value) { return this; } /** - * .a2a.v1.Message request = 1 [(.google.api.field_behavior) = REQUIRED]; + * .a2a.v1.Message request = 1 [json_name = "message", (.google.api.field_behavior) = REQUIRED]; */ public Builder setRequest( io.a2a.grpc.Message.Builder builderForValue) { @@ -573,7 +573,7 @@ public Builder setRequest( return this; } /** - * .a2a.v1.Message request = 1 [(.google.api.field_behavior) = REQUIRED]; + * .a2a.v1.Message request = 1 [json_name = "message", (.google.api.field_behavior) = REQUIRED]; */ public Builder mergeRequest(io.a2a.grpc.Message value) { if (requestBuilder_ == null) { @@ -594,7 +594,7 @@ public Builder mergeRequest(io.a2a.grpc.Message value) { return this; } /** - * .a2a.v1.Message request = 1 [(.google.api.field_behavior) = REQUIRED]; + * .a2a.v1.Message request = 1 [json_name = "message", (.google.api.field_behavior) = REQUIRED]; */ public Builder clearRequest() { bitField0_ = (bitField0_ & ~0x00000001); @@ -607,7 +607,7 @@ public Builder clearRequest() { return this; } /** - * .a2a.v1.Message request = 1 [(.google.api.field_behavior) = REQUIRED]; + * .a2a.v1.Message request = 1 [json_name = "message", (.google.api.field_behavior) = REQUIRED]; */ public io.a2a.grpc.Message.Builder getRequestBuilder() { bitField0_ |= 0x00000001; @@ -615,7 +615,7 @@ public io.a2a.grpc.Message.Builder getRequestBuilder() { return internalGetRequestFieldBuilder().getBuilder(); } /** - * .a2a.v1.Message request = 1 [(.google.api.field_behavior) = REQUIRED]; + * .a2a.v1.Message request = 1 [json_name = "message", (.google.api.field_behavior) = REQUIRED]; */ public io.a2a.grpc.MessageOrBuilder getRequestOrBuilder() { if (requestBuilder_ != null) { @@ -626,7 +626,7 @@ public io.a2a.grpc.MessageOrBuilder getRequestOrBuilder() { } } /** - * .a2a.v1.Message request = 1 [(.google.api.field_behavior) = REQUIRED]; + * .a2a.v1.Message request = 1 [json_name = "message", (.google.api.field_behavior) = REQUIRED]; */ private com.google.protobuf.SingleFieldBuilder< io.a2a.grpc.Message, io.a2a.grpc.Message.Builder, io.a2a.grpc.MessageOrBuilder> diff --git a/spec-grpc/src/main/java/io/a2a/grpc/SendMessageRequestOrBuilder.java b/spec-grpc/src/main/java/io/a2a/grpc/SendMessageRequestOrBuilder.java index fc3632f6b..13dae6c0e 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/SendMessageRequestOrBuilder.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/SendMessageRequestOrBuilder.java @@ -11,17 +11,17 @@ public interface SendMessageRequestOrBuilder extends com.google.protobuf.MessageOrBuilder { /** - * .a2a.v1.Message request = 1 [(.google.api.field_behavior) = REQUIRED]; + * .a2a.v1.Message request = 1 [json_name = "message", (.google.api.field_behavior) = REQUIRED]; * @return Whether the request field is set. */ boolean hasRequest(); /** - * .a2a.v1.Message request = 1 [(.google.api.field_behavior) = REQUIRED]; + * .a2a.v1.Message request = 1 [json_name = "message", (.google.api.field_behavior) = REQUIRED]; * @return The request. */ io.a2a.grpc.Message getRequest(); /** - * .a2a.v1.Message request = 1 [(.google.api.field_behavior) = REQUIRED]; + * .a2a.v1.Message request = 1 [json_name = "message", (.google.api.field_behavior) = REQUIRED]; */ io.a2a.grpc.MessageOrBuilder getRequestOrBuilder(); diff --git a/spec-grpc/src/main/java/io/a2a/grpc/utils/ProtoUtils.java b/spec-grpc/src/main/java/io/a2a/grpc/utils/ProtoUtils.java index 73158ecf2..52a6b6719 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/utils/ProtoUtils.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/utils/ProtoUtils.java @@ -18,6 +18,7 @@ import io.a2a.spec.APIKeySecurityScheme; import io.a2a.spec.AgentCapabilities; import io.a2a.spec.AgentCard; +import io.a2a.spec.AgentCardSignature; import io.a2a.spec.AgentExtension; import io.a2a.spec.AgentInterface; import io.a2a.spec.AgentProvider; @@ -35,10 +36,13 @@ import io.a2a.spec.GetTaskPushNotificationConfigParams; import io.a2a.spec.HTTPAuthSecurityScheme; import io.a2a.spec.ImplicitOAuthFlow; +import io.a2a.spec.InvalidParamsError; +import io.a2a.spec.InvalidRequestError; import io.a2a.spec.ListTaskPushNotificationConfigParams; import io.a2a.spec.Message; import io.a2a.spec.MessageSendConfiguration; import io.a2a.spec.MessageSendParams; +import io.a2a.spec.MutualTLSSecurityScheme; import io.a2a.spec.OAuth2SecurityScheme; import io.a2a.spec.OAuthFlows; import io.a2a.spec.OpenIdConnectSecurityScheme; @@ -124,6 +128,9 @@ public static io.a2a.grpc.AgentCard agentCard(AgentCard agentCard) { builder.addAllSkills(agentCard.skills().stream().map(ToProto::agentSkill).collect(Collectors.toList())); } builder.setSupportsAuthenticatedExtendedCard(agentCard.supportsAuthenticatedExtendedCard()); + if (agentCard.signatures() != null) { + builder.addAllSignatures(agentCard.signatures().stream().map(ToProto::agentCardSignature).collect(Collectors.toList())); + } return builder.build(); } @@ -395,6 +402,27 @@ private static io.a2a.grpc.AgentSkill agentSkill(AgentSkill agentSkill) { if (agentSkill.outputModes() != null) { builder.addAllOutputModes(agentSkill.outputModes()); } + if (agentSkill.security() != null) { + builder.addAllSecurity(agentSkill.security().stream().map(s -> { + io.a2a.grpc.Security.Builder securityBuilder = io.a2a.grpc.Security.newBuilder(); + s.forEach((key, value) -> { + io.a2a.grpc.StringList.Builder stringListBuilder = io.a2a.grpc.StringList.newBuilder(); + stringListBuilder.addAllList(value); + securityBuilder.putSchemes(key, stringListBuilder.build()); + }); + return securityBuilder.build(); + }).collect(Collectors.toList())); + } + return builder.build(); + } + + private static io.a2a.grpc.AgentCardSignature agentCardSignature(AgentCardSignature agentCardSignature) { + io.a2a.grpc.AgentCardSignature.Builder builder = io.a2a.grpc.AgentCardSignature.newBuilder(); + builder.setProtected(agentCardSignature.protectedHeader()); + builder.setSignature(agentCardSignature.signature()); + if (agentCardSignature.header() != null) { + builder.setHeader(struct(agentCardSignature.header())); + } return builder.build(); } @@ -408,6 +436,8 @@ private static io.a2a.grpc.SecurityScheme securityScheme(SecurityScheme security builder.setOauth2SecurityScheme(oauthSecurityScheme((OAuth2SecurityScheme) securityScheme)); } else if (securityScheme instanceof OpenIdConnectSecurityScheme) { builder.setOpenIdConnectSecurityScheme(openIdConnectSecurityScheme((OpenIdConnectSecurityScheme) securityScheme)); + } else if (securityScheme instanceof MutualTLSSecurityScheme) { + builder.setMtlsSecurityScheme(mutualTlsSecurityScheme((MutualTLSSecurityScheme) securityScheme)); } return builder.build(); } @@ -448,6 +478,9 @@ private static io.a2a.grpc.OAuth2SecurityScheme oauthSecurityScheme(OAuth2Securi if (oauth2SecurityScheme.getFlows() != null) { builder.setFlows(oauthFlows(oauth2SecurityScheme.getFlows())); } + if (oauth2SecurityScheme.getOauth2MetadataUrl() != null) { + builder.setOauth2MetadataUrl(oauth2SecurityScheme.getOauth2MetadataUrl()); + } return builder.build(); } @@ -538,6 +571,14 @@ private static io.a2a.grpc.OpenIdConnectSecurityScheme openIdConnectSecuritySche return builder.build(); } + private static io.a2a.grpc.MutualTlsSecurityScheme mutualTlsSecurityScheme(MutualTLSSecurityScheme mutualTlsSecurityScheme) { + io.a2a.grpc.MutualTlsSecurityScheme.Builder builder = io.a2a.grpc.MutualTlsSecurityScheme.newBuilder(); + if (mutualTlsSecurityScheme.getDescription() != null) { + builder.setDescription(mutualTlsSecurityScheme.getDescription()); + } + return builder.build(); + } + private static io.a2a.grpc.AgentInterface agentInterface(AgentInterface agentInterface) { io.a2a.grpc.AgentInterface.Builder builder = io.a2a.grpc.AgentInterface.newBuilder(); if (agentInterface.transport() != null) { @@ -751,12 +792,15 @@ public static Task task(io.a2a.grpc.Task task) { } public static Message message(io.a2a.grpc.Message message) { + if (message.getMessageId().isEmpty()) { + throw new InvalidParamsError(); + } return new Message( role(message.getRole()), message.getContentList().stream().map(item -> part(item)).collect(Collectors.toList()), message.getMessageId().isEmpty() ? null : message.getMessageId(), message.getContextId().isEmpty() ? null : message.getContextId(), - message.getTaskId(), + message.getTaskId().isEmpty() ? null : message.getTaskId(), null, // referenceTaskIds is not in grpc message struct(message.getMetadata()) ); @@ -801,7 +845,7 @@ private static Part part(io.a2a.grpc.Part part) { } else if (part.hasData()) { return dataPart(part.getData()); } - return null; + throw new InvalidRequestError(); } private static TextPart textPart(String text) { @@ -814,7 +858,7 @@ private static FilePart filePart(io.a2a.grpc.FilePart filePart) { } else if (filePart.hasFileWithUri()) { return new FilePart(new FileWithUri(filePart.getMimeType(), null, filePart.getFileWithUri())); } - return null; + throw new InvalidRequestError(); } private static DataPart dataPart(io.a2a.grpc.DataPart dataPart) { @@ -839,7 +883,7 @@ private static Message.Role role(io.a2a.grpc.Role role) { case ROLE_AGENT -> Message.Role.AGENT; default -> - null; + throw new InvalidRequestError(); }; } @@ -895,7 +939,7 @@ private static Object value(Value value) { return value.getStringValue(); case NULL_VALUE: default: - return null; + throw new InvalidRequestError(); } } } diff --git a/spec-grpc/src/main/proto/a2a.proto b/spec-grpc/src/main/proto/a2a.proto index 8bada0795..8b1230059 100644 --- a/spec-grpc/src/main/proto/a2a.proto +++ b/spec-grpc/src/main/proto/a2a.proto @@ -9,7 +9,7 @@ import "google/protobuf/empty.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/timestamp.proto"; -// Copied from https://github.com/a2aproject/A2A/blob/v0.2.6/specification/grpc/a2a.proto +// Copied from https://github.com/a2aproject/A2A/blob/v0.3.0/specification/grpc/a2a.proto // The only change is the 'java_package' update option csharp_namespace = "A2a.V1"; @@ -345,6 +345,7 @@ message AgentInterface { // - Skills; a set of actions/solutions the agent can perform // - Default modalities/content types supported by the agent. // - Authentication requirements +// Next ID: 18 message AgentCard { // The version of the A2A protocol this agent supports. string protocol_version = 16; @@ -375,6 +376,18 @@ message AgentCard { map security_schemes = 8; // protolint:disable REPEATED_FIELD_NAMES_PLURALIZED // Security requirements for contacting the agent. + // This list can be seen as an OR of ANDs. Each object in the list describes + // one possible set of security requirements that must be present on a + // request. This allows specifying, for example, "callers must either use + // OAuth OR an API Key AND mTLS." + // Example: + // security { + // schemes { key: "oauth" value { list: ["read"] } } + // } + // security { + // schemes { key: "api-key" } + // schemes { key: "mtls" } + // } repeated Security security = 9; // protolint:enable REPEATED_FIELD_NAMES_PLURALIZED // The set of interaction modes that the agent supports across all skills. @@ -390,6 +403,8 @@ message AgentCard { // the user is authenticated, i.e. is the card from .well-known // different than the card from GetAgentCard. bool supports_authenticated_extended_card = 13; + // JSON Web Signatures computed for this AgentCard. + repeated AgentCardSignature signatures = 17; } // Represents information about the service provider of an agent. @@ -452,6 +467,24 @@ message AgentSkill { repeated string input_modes = 6; // Possible output modalities produced repeated string output_modes = 7; + // protolint:disable REPEATED_FIELD_NAMES_PLURALIZED + // Security schemes necessary for the agent to leverage this skill. + // As in the overall AgentCard.security, this list represents a logical OR of + // security requirement objects. Each object is a set of security schemes + // that must be used together (a logical AND). + repeated Security security = 8; +} + +// AgentCardSignature represents a JWS signature of an AgentCard. +// This follows the JSON format of an RFC 7515 JSON Web Signature (JWS). +message AgentCardSignature { + // The protected JWS header for the signature. This is always a + // base64url-encoded JSON object. Required. + string protected = 1 [(google.api.field_behavior) = REQUIRED]; + // The computed signature, base64url-encoded. Required. + string signature = 2 [(google.api.field_behavior) = REQUIRED]; + // The unprotected JWS header values. + google.protobuf.Struct header = 3; } message TaskPushNotificationConfig { @@ -476,6 +509,7 @@ message SecurityScheme { HTTPAuthSecurityScheme http_auth_security_scheme = 2; OAuth2SecurityScheme oauth2_security_scheme = 3; OpenIdConnectSecurityScheme open_id_connect_security_scheme = 4; + MutualTlsSecurityScheme mtls_security_scheme = 5; } } @@ -507,6 +541,9 @@ message OAuth2SecurityScheme { string description = 1; // An object containing configuration information for the flow types supported OAuthFlows flows = 2; + // URL to the oauth2 authorization server metadata + // [RFC8414](https://datatracker.ietf.org/doc/html/rfc8414). TLS is required. + string oauth2_metadata_url = 3; } message OpenIdConnectSecurityScheme { @@ -517,6 +554,11 @@ message OpenIdConnectSecurityScheme { string open_id_connect_url = 2; } +message MutualTlsSecurityScheme { + // Description of this security scheme. + string description = 1; +} + message OAuthFlows { oneof flow { AuthorizationCodeOAuthFlow authorization_code = 1; @@ -579,7 +621,8 @@ message PasswordOAuthFlow { ///////////// Request Messages /////////// message SendMessageRequest { - Message request = 1 [(google.api.field_behavior) = REQUIRED]; + Message request = 1 + [(google.api.field_behavior) = REQUIRED, json_name = "message"]; SendMessageConfiguration configuration = 2; google.protobuf.Struct metadata = 3; } diff --git a/spec-grpc/src/main/resources/META-INF/beans.xml b/spec-grpc/src/main/resources/META-INF/beans.xml index be7990041..e69de29bb 100644 --- a/spec-grpc/src/main/resources/META-INF/beans.xml +++ b/spec-grpc/src/main/resources/META-INF/beans.xml @@ -1,6 +0,0 @@ - - - \ No newline at end of file diff --git a/spec/pom.xml b/spec/pom.xml index ce67def18..ee377b421 100644 --- a/spec/pom.xml +++ b/spec/pom.xml @@ -7,7 +7,7 @@ io.github.a2asdk a2a-java-sdk-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT a2a-java-sdk-spec diff --git a/spec/src/main/java/io/a2a/spec/APIKeySecurityScheme.java b/spec/src/main/java/io/a2a/spec/APIKeySecurityScheme.java index acf33feba..73ecd134c 100644 --- a/spec/src/main/java/io/a2a/spec/APIKeySecurityScheme.java +++ b/spec/src/main/java/io/a2a/spec/APIKeySecurityScheme.java @@ -9,7 +9,7 @@ import io.a2a.util.Assert; /** - * Represents an API Key security scheme. + * Defines a security scheme using an API key. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/AgentCapabilities.java b/spec/src/main/java/io/a2a/spec/AgentCapabilities.java index 641f56ccb..1c6fdf1b2 100644 --- a/spec/src/main/java/io/a2a/spec/AgentCapabilities.java +++ b/spec/src/main/java/io/a2a/spec/AgentCapabilities.java @@ -6,7 +6,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; /** - * An agent's capabilities. + * Defines optional capabilities supported by an agent. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/AgentCard.java b/spec/src/main/java/io/a2a/spec/AgentCard.java index e394fb626..a2e806ffc 100644 --- a/spec/src/main/java/io/a2a/spec/AgentCard.java +++ b/spec/src/main/java/io/a2a/spec/AgentCard.java @@ -1,5 +1,6 @@ package io.a2a.spec; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -8,8 +9,9 @@ import io.a2a.util.Assert; /** - * A public metadata file that describes an agent's capabilities, skills, endpoint URL, and - * authentication requirements. Clients use this for discovery. + * The AgentCard is a self-describing manifest for an agent. It provides essential + * metadata including the agent's identity, capabilities, skills, supported + * communication methods, and security requirements. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) @@ -18,9 +20,11 @@ public record AgentCard(String name, String description, String url, AgentProvid List defaultInputModes, List defaultOutputModes, List skills, boolean supportsAuthenticatedExtendedCard, Map securitySchemes, List>> security, String iconUrl, List additionalInterfaces, - String preferredTransport, String protocolVersion) { + String preferredTransport, String protocolVersion, List signatures) { private static final String TEXT_MODE = "text"; + private static final String DEFAULT_PROTOCOL_VERSION = "0.3.0"; + private static final TransportProtocol DEFAULT_TRANSPORT = TransportProtocol.JSONRPC; public AgentCard { Assert.checkNotNullParam("capabilities", capabilities); @@ -31,7 +35,12 @@ public record AgentCard(String name, String description, String url, AgentProvid Assert.checkNotNullParam("skills", skills); Assert.checkNotNullParam("url", url); Assert.checkNotNullParam("version", version); - Assert.checkNotNullParam("protocolVersion", protocolVersion); + if (protocolVersion == null) { + protocolVersion = DEFAULT_PROTOCOL_VERSION; + } + if (preferredTransport == null) { + preferredTransport = DEFAULT_TRANSPORT.asString(); + } } public static class Builder { @@ -50,8 +59,10 @@ public static class Builder { private List>> security; private String iconUrl; private List additionalInterfaces; - String preferredTransport; - String protocolVersion; + private String preferredTransport; + private String protocolVersion; + private List signatures; + public Builder name(String name) { this.name = name; @@ -138,11 +149,24 @@ public Builder protocolVersion(String protocolVersion) { return this; } + public Builder signatures(List signatures) { + this.signatures = signatures; + return this; + } + public AgentCard build() { + if (preferredTransport == null) { + preferredTransport = DEFAULT_TRANSPORT.asString(); + } + if (additionalInterfaces == null) { + // should include an entry matching the main 'url' and 'preferredTransport' + additionalInterfaces = new ArrayList<>(); + additionalInterfaces.add(new AgentInterface(preferredTransport, url)); + } return new AgentCard(name, description, url, provider, version, documentationUrl, capabilities, defaultInputModes, defaultOutputModes, skills, supportsAuthenticatedExtendedCard, securitySchemes, security, iconUrl, - additionalInterfaces, preferredTransport, protocolVersion); + additionalInterfaces, preferredTransport, protocolVersion, signatures); } } } diff --git a/spec/src/main/java/io/a2a/spec/AgentCardSignature.java b/spec/src/main/java/io/a2a/spec/AgentCardSignature.java new file mode 100644 index 000000000..4e383d998 --- /dev/null +++ b/spec/src/main/java/io/a2a/spec/AgentCardSignature.java @@ -0,0 +1,49 @@ +package io.a2a.spec; + +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +import io.a2a.util.Assert; + +/** + * Represents a JWS signature of an AgentCard. + * This follows the JSON format of an RFC 7515 JSON Web Signature (JWS). + */ +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonIgnoreProperties(ignoreUnknown = true) +public record AgentCardSignature(Map header, @JsonProperty("protected") String protectedHeader, + String signature) { + + public AgentCardSignature { + Assert.checkNotNullParam("protectedHeader", protectedHeader); + Assert.checkNotNullParam("signature", signature); + } + + public static class Builder { + private Map header; + String protectedHeader; + String signature; + + public Builder header(Map header) { + this.header = header; + return this; + } + + public Builder protectedHeader(String protectedHeader) { + this.protectedHeader = protectedHeader; + return this; + } + + public Builder signature(String signature) { + this.signature = signature; + return this; + } + + public AgentCardSignature build() { + return new AgentCardSignature(header, protectedHeader, signature); + } + } +} diff --git a/spec/src/main/java/io/a2a/spec/AgentExtension.java b/spec/src/main/java/io/a2a/spec/AgentExtension.java index 931bc1c16..053855976 100644 --- a/spec/src/main/java/io/a2a/spec/AgentExtension.java +++ b/spec/src/main/java/io/a2a/spec/AgentExtension.java @@ -4,6 +4,9 @@ import io.a2a.util.Assert; +/** + * A declaration of a protocol extension supported by an Agent. + */ public record AgentExtension (String description, Map params, boolean required, String uri) { public AgentExtension { diff --git a/spec/src/main/java/io/a2a/spec/AgentInterface.java b/spec/src/main/java/io/a2a/spec/AgentInterface.java index ab2b7307d..db81ce8f0 100644 --- a/spec/src/main/java/io/a2a/spec/AgentInterface.java +++ b/spec/src/main/java/io/a2a/spec/AgentInterface.java @@ -5,7 +5,7 @@ import io.a2a.util.Assert; /** - * Provides a declaration of the target url and the supported transport to interact with the agent. + * Declares a combination of a target URL and a transport protocol for interacting with the agent. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/AgentProvider.java b/spec/src/main/java/io/a2a/spec/AgentProvider.java index 363d42b03..fa57b4478 100644 --- a/spec/src/main/java/io/a2a/spec/AgentProvider.java +++ b/spec/src/main/java/io/a2a/spec/AgentProvider.java @@ -5,7 +5,7 @@ import io.a2a.util.Assert; /** - * An agent provider. + * Represents the service provider of an agent. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/AgentSkill.java b/spec/src/main/java/io/a2a/spec/AgentSkill.java index ce9f4811e..3802b3418 100644 --- a/spec/src/main/java/io/a2a/spec/AgentSkill.java +++ b/spec/src/main/java/io/a2a/spec/AgentSkill.java @@ -1,18 +1,20 @@ package io.a2a.spec; import java.util.List; +import java.util.Map; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import io.a2a.util.Assert; /** - * An agent skill. + * The set of skills, or distinct capabilities, that the agent can perform. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record AgentSkill(String id, String name, String description, List tags, - List examples, List inputModes, List outputModes) { + List examples, List inputModes, List outputModes, + List>> security) { public AgentSkill { Assert.checkNotNullParam("description", description); @@ -30,6 +32,7 @@ public static class Builder { private List examples; private List inputModes; private List outputModes; + private List>> security; public Builder id(String id) { this.id = id; @@ -66,8 +69,13 @@ public Builder outputModes(List outputModes) { return this; } + public Builder security(List>> security) { + this.security = security; + return this; + } + public AgentSkill build() { - return new AgentSkill(id, name, description, tags, examples, inputModes, outputModes); + return new AgentSkill(id, name, description, tags, examples, inputModes, outputModes, security); } } } diff --git a/spec/src/main/java/io/a2a/spec/Artifact.java b/spec/src/main/java/io/a2a/spec/Artifact.java index 5a5baa063..cb4d1504b 100644 --- a/spec/src/main/java/io/a2a/spec/Artifact.java +++ b/spec/src/main/java/io/a2a/spec/Artifact.java @@ -8,8 +8,7 @@ import io.a2a.util.Assert; /** - * Represents outputs generated by an agent during a task (e.g., generated files or final structured - * data). Contains parts. + * Represents a file, data structure, or other resource generated by an agent during a task. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/AuthenticatedExtendedCardNotConfiguredError.java b/spec/src/main/java/io/a2a/spec/AuthenticatedExtendedCardNotConfiguredError.java new file mode 100644 index 000000000..323cd147d --- /dev/null +++ b/spec/src/main/java/io/a2a/spec/AuthenticatedExtendedCardNotConfiguredError.java @@ -0,0 +1,35 @@ +package io.a2a.spec; + +import static io.a2a.util.Utils.defaultIfNull; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * An A2A-specific error indicating that the agent does not have an + * Authenticated Extended Card configured + */ +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonIgnoreProperties(ignoreUnknown = true) +public class AuthenticatedExtendedCardNotConfiguredError extends JSONRPCError { + + public final static Integer DEFAULT_CODE = -32007; + + @JsonCreator + public AuthenticatedExtendedCardNotConfiguredError( + @JsonProperty("code") Integer code, + @JsonProperty("message") String message, + @JsonProperty("data") Object data) { + super( + defaultIfNull(code, DEFAULT_CODE), + defaultIfNull(message, "Authenticated Extended Card not configured"), + data); + } + + public AuthenticatedExtendedCardNotConfiguredError() { + this(null, null, null); + } + +} diff --git a/spec/src/main/java/io/a2a/spec/AuthorizationCodeOAuthFlow.java b/spec/src/main/java/io/a2a/spec/AuthorizationCodeOAuthFlow.java index 0723a1281..afa6fed72 100644 --- a/spec/src/main/java/io/a2a/spec/AuthorizationCodeOAuthFlow.java +++ b/spec/src/main/java/io/a2a/spec/AuthorizationCodeOAuthFlow.java @@ -8,7 +8,7 @@ import io.a2a.util.Assert; /** - * Configuration for the OAuth Authorization Code flow. + * Defines configuration details for the OAuth 2.0 Authorization Code flow. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/ClientCredentialsOAuthFlow.java b/spec/src/main/java/io/a2a/spec/ClientCredentialsOAuthFlow.java index 05322cc0b..372b57d78 100644 --- a/spec/src/main/java/io/a2a/spec/ClientCredentialsOAuthFlow.java +++ b/spec/src/main/java/io/a2a/spec/ClientCredentialsOAuthFlow.java @@ -9,7 +9,7 @@ import io.a2a.util.Assert; /** - * Configuration for the OAuth Client Credentials flow. + * Defines configuration details for the OAuth 2.0 Client Credentials flow. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/ContentTypeNotSupportedError.java b/spec/src/main/java/io/a2a/spec/ContentTypeNotSupportedError.java index d05ee3202..3aa245ca2 100644 --- a/spec/src/main/java/io/a2a/spec/ContentTypeNotSupportedError.java +++ b/spec/src/main/java/io/a2a/spec/ContentTypeNotSupportedError.java @@ -7,6 +7,10 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +/** + * An A2A-specific error indicating an incompatibility between the requested + * content types and the agent's capabilities. + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public class ContentTypeNotSupportedError extends JSONRPCError { diff --git a/spec/src/main/java/io/a2a/spec/DataPart.java b/spec/src/main/java/io/a2a/spec/DataPart.java index 1449f55ac..b40cbb839 100644 --- a/spec/src/main/java/io/a2a/spec/DataPart.java +++ b/spec/src/main/java/io/a2a/spec/DataPart.java @@ -9,7 +9,7 @@ import io.a2a.util.Assert; /** - * A fundamental data unit within a Message or Artifact. + * Represents a structured data segment (e.g., JSON) within a message or artifact. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/FilePart.java b/spec/src/main/java/io/a2a/spec/FilePart.java index f4c1d0f8e..82c2a4f5f 100644 --- a/spec/src/main/java/io/a2a/spec/FilePart.java +++ b/spec/src/main/java/io/a2a/spec/FilePart.java @@ -9,7 +9,8 @@ import io.a2a.util.Assert; /** - * A fundamental file unit within a Message or Artifact. + * Represents a file segment within a message or artifact. The file content can be + * provided either directly as bytes or as a URI. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/FileWithBytes.java b/spec/src/main/java/io/a2a/spec/FileWithBytes.java index e2259e902..782bc2c02 100644 --- a/spec/src/main/java/io/a2a/spec/FileWithBytes.java +++ b/spec/src/main/java/io/a2a/spec/FileWithBytes.java @@ -3,6 +3,9 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; +/** + * Represents a file with its content provided directly as a base64-encoded string. + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record FileWithBytes(String mimeType, String name, String bytes) implements FileContent { diff --git a/spec/src/main/java/io/a2a/spec/FileWithUri.java b/spec/src/main/java/io/a2a/spec/FileWithUri.java index 65db42dc5..afb3a87d8 100644 --- a/spec/src/main/java/io/a2a/spec/FileWithUri.java +++ b/spec/src/main/java/io/a2a/spec/FileWithUri.java @@ -3,6 +3,9 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; +/** + * Represents a file with its content located at a specific URI. + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record FileWithUri(String mimeType, String name, String uri) implements FileContent { diff --git a/spec/src/main/java/io/a2a/spec/GetAuthenticatedExtendedCardRequest.java b/spec/src/main/java/io/a2a/spec/GetAuthenticatedExtendedCardRequest.java new file mode 100644 index 000000000..9d561c2d2 --- /dev/null +++ b/spec/src/main/java/io/a2a/spec/GetAuthenticatedExtendedCardRequest.java @@ -0,0 +1,70 @@ +package io.a2a.spec; + +import java.util.UUID; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +import io.a2a.util.Assert; +import io.a2a.util.Utils; + +/** + * Represents a JSON-RPC request for the `agent/getAuthenticatedExtendedCard` method. + */ +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonIgnoreProperties(ignoreUnknown = true) +public final class GetAuthenticatedExtendedCardRequest extends NonStreamingJSONRPCRequest { + + public static final String METHOD = "agent/getAuthenticatedExtendedCard"; + + @JsonCreator + public GetAuthenticatedExtendedCardRequest(@JsonProperty("jsonrpc") String jsonrpc, @JsonProperty("id") Object id, + @JsonProperty("method") String method, @JsonProperty("params") Void params) { + if (jsonrpc != null && ! jsonrpc.equals(JSONRPC_VERSION)) { + throw new IllegalArgumentException("Invalid JSON-RPC protocol version"); + } + Assert.checkNotNullParam("method", method); + if (! method.equals(METHOD)) { + throw new IllegalArgumentException("Invalid GetAuthenticatedExtendedCardRequest method"); + } + Assert.isNullOrStringOrInteger(id); + this.jsonrpc = Utils.defaultIfNull(jsonrpc, JSONRPC_VERSION); + this.id = id; + this.method = method; + this.params = params; + } + + public GetAuthenticatedExtendedCardRequest(String id) { + this(null, id, METHOD, null); + } + + public static class Builder { + private String jsonrpc; + private Object id; + private String method; + + public GetAuthenticatedExtendedCardRequest.Builder jsonrpc(String jsonrpc) { + this.jsonrpc = jsonrpc; + return this; + } + + public GetAuthenticatedExtendedCardRequest.Builder id(Object id) { + this.id = id; + return this; + } + + public GetAuthenticatedExtendedCardRequest.Builder method(String method) { + this.method = method; + return this; + } + + public GetAuthenticatedExtendedCardRequest build() { + if (id == null) { + id = UUID.randomUUID().toString(); + } + return new GetAuthenticatedExtendedCardRequest(jsonrpc, id, method, null); + } + } +} diff --git a/spec/src/main/java/io/a2a/spec/GetAuthenticatedExtendedCardResponse.java b/spec/src/main/java/io/a2a/spec/GetAuthenticatedExtendedCardResponse.java new file mode 100644 index 000000000..ec624e77d --- /dev/null +++ b/spec/src/main/java/io/a2a/spec/GetAuthenticatedExtendedCardResponse.java @@ -0,0 +1,30 @@ +package io.a2a.spec; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * A response for the `agent/getAuthenticatedExtendedCard` method. + */ +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonIgnoreProperties(ignoreUnknown = true) +public final class GetAuthenticatedExtendedCardResponse extends JSONRPCResponse { + + @JsonCreator + public GetAuthenticatedExtendedCardResponse(@JsonProperty("jsonrpc") String jsonrpc, @JsonProperty("id") Object id, + @JsonProperty("result") AgentCard result, + @JsonProperty("error") JSONRPCError error) { + super(jsonrpc, id, result, error, AgentCard.class); + } + + public GetAuthenticatedExtendedCardResponse(Object id, JSONRPCError error) { + this(null, id, null, error); + } + + public GetAuthenticatedExtendedCardResponse(Object id, AgentCard result) { + this(null, id, result, null); + } + +} diff --git a/spec/src/main/java/io/a2a/spec/HTTPAuthSecurityScheme.java b/spec/src/main/java/io/a2a/spec/HTTPAuthSecurityScheme.java index 029419a19..0d6ed417f 100644 --- a/spec/src/main/java/io/a2a/spec/HTTPAuthSecurityScheme.java +++ b/spec/src/main/java/io/a2a/spec/HTTPAuthSecurityScheme.java @@ -8,7 +8,7 @@ import io.a2a.util.Assert; /** - * Represents an HTTP authentication security scheme. + * Defines a security scheme using HTTP authentication. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/ImplicitOAuthFlow.java b/spec/src/main/java/io/a2a/spec/ImplicitOAuthFlow.java index 46e76cc84..8e2d529ea 100644 --- a/spec/src/main/java/io/a2a/spec/ImplicitOAuthFlow.java +++ b/spec/src/main/java/io/a2a/spec/ImplicitOAuthFlow.java @@ -8,7 +8,7 @@ import io.a2a.util.Assert; /** - * Configuration for the OAuth Implicit flow. + * Defines configuration details for the OAuth 2.0 Implicit flow. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/InternalError.java b/spec/src/main/java/io/a2a/spec/InternalError.java index 47f1a332e..ae52ecb70 100644 --- a/spec/src/main/java/io/a2a/spec/InternalError.java +++ b/spec/src/main/java/io/a2a/spec/InternalError.java @@ -7,6 +7,9 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +/** + * An error indicating an internal error on the server. + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public class InternalError extends JSONRPCError { diff --git a/spec/src/main/java/io/a2a/spec/InvalidAgentResponseError.java b/spec/src/main/java/io/a2a/spec/InvalidAgentResponseError.java index 7b0476e2a..faab71a96 100644 --- a/spec/src/main/java/io/a2a/spec/InvalidAgentResponseError.java +++ b/spec/src/main/java/io/a2a/spec/InvalidAgentResponseError.java @@ -8,7 +8,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; /** - * A2A specific error indicating agent returned invalid response for the current method. + * An A2A-specific error indicating that the agent returned a response that + * does not conform to the specification for the current method. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/InvalidParamsError.java b/spec/src/main/java/io/a2a/spec/InvalidParamsError.java index 69cd1fadc..c71ea14bf 100644 --- a/spec/src/main/java/io/a2a/spec/InvalidParamsError.java +++ b/spec/src/main/java/io/a2a/spec/InvalidParamsError.java @@ -7,6 +7,9 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +/** + * An error indicating that the method parameters are invalid. + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public class InvalidParamsError extends JSONRPCError { diff --git a/spec/src/main/java/io/a2a/spec/InvalidRequestError.java b/spec/src/main/java/io/a2a/spec/InvalidRequestError.java index 17d3227dc..4d9e50779 100644 --- a/spec/src/main/java/io/a2a/spec/InvalidRequestError.java +++ b/spec/src/main/java/io/a2a/spec/InvalidRequestError.java @@ -7,6 +7,9 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +/** + * An error indicating that the JSON sent is not a valid Request object. + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public class InvalidRequestError extends JSONRPCError { diff --git a/spec/src/main/java/io/a2a/spec/JSONParseError.java b/spec/src/main/java/io/a2a/spec/JSONParseError.java index 2e3e96dbe..d596c0701 100644 --- a/spec/src/main/java/io/a2a/spec/JSONParseError.java +++ b/spec/src/main/java/io/a2a/spec/JSONParseError.java @@ -7,6 +7,9 @@ import static io.a2a.util.Utils.defaultIfNull; +/** + * An error indicating that the server received invalid JSON. + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public class JSONParseError extends JSONRPCError implements A2AError { diff --git a/spec/src/main/java/io/a2a/spec/JSONRPCError.java b/spec/src/main/java/io/a2a/spec/JSONRPCError.java index b682203d4..776b9c8c6 100644 --- a/spec/src/main/java/io/a2a/spec/JSONRPCError.java +++ b/spec/src/main/java/io/a2a/spec/JSONRPCError.java @@ -10,7 +10,7 @@ import io.a2a.util.Assert; /** - * Represents a JSONRPC error. + * Represents a JSON-RPC 2.0 Error object, included in an error response. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonDeserialize(using = JSONRPCErrorDeserializer.class) diff --git a/spec/src/main/java/io/a2a/spec/JSONRPCMessage.java b/spec/src/main/java/io/a2a/spec/JSONRPCMessage.java index 20d3a117a..68e2d16fd 100644 --- a/spec/src/main/java/io/a2a/spec/JSONRPCMessage.java +++ b/spec/src/main/java/io/a2a/spec/JSONRPCMessage.java @@ -1,7 +1,7 @@ package io.a2a.spec; /** - * Represents a JSONRPC message. + * Defines the base structure for any JSON-RPC 2.0 request, response, or notification. */ public sealed interface JSONRPCMessage permits JSONRPCRequest, JSONRPCResponse { diff --git a/spec/src/main/java/io/a2a/spec/JSONRPCRequestDeserializerBase.java b/spec/src/main/java/io/a2a/spec/JSONRPCRequestDeserializerBase.java index cf0134efe..2af7d0513 100644 --- a/spec/src/main/java/io/a2a/spec/JSONRPCRequestDeserializerBase.java +++ b/spec/src/main/java/io/a2a/spec/JSONRPCRequestDeserializerBase.java @@ -82,7 +82,8 @@ protected static boolean isValidMethodName(String methodName) { || methodName.equals(SendMessageRequest.METHOD) || methodName.equals(SendStreamingMessageRequest.METHOD) || methodName.equals(ListTaskPushNotificationConfigRequest.METHOD) - || methodName.equals(DeleteTaskPushNotificationConfigRequest.METHOD)); + || methodName.equals(DeleteTaskPushNotificationConfigRequest.METHOD) + || methodName.equals(GetAuthenticatedExtendedCardRequest.METHOD)); } } diff --git a/spec/src/main/java/io/a2a/spec/JSONRPCResponse.java b/spec/src/main/java/io/a2a/spec/JSONRPCResponse.java index 3a382b1a7..858a4541e 100644 --- a/spec/src/main/java/io/a2a/spec/JSONRPCResponse.java +++ b/spec/src/main/java/io/a2a/spec/JSONRPCResponse.java @@ -2,7 +2,6 @@ import static io.a2a.util.Utils.defaultIfNull; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; @@ -15,7 +14,8 @@ @JsonIgnoreProperties(ignoreUnknown = true) public abstract sealed class JSONRPCResponse implements JSONRPCMessage permits SendStreamingMessageResponse, GetTaskResponse, CancelTaskResponse, SetTaskPushNotificationConfigResponse, GetTaskPushNotificationConfigResponse, - SendMessageResponse, DeleteTaskPushNotificationConfigResponse, ListTaskPushNotificationConfigResponse, JSONRPCErrorResponse { + SendMessageResponse, DeleteTaskPushNotificationConfigResponse, ListTaskPushNotificationConfigResponse, JSONRPCErrorResponse, + GetAuthenticatedExtendedCardResponse { protected String jsonrpc; protected Object id; diff --git a/spec/src/main/java/io/a2a/spec/Message.java b/spec/src/main/java/io/a2a/spec/Message.java index f17646a0f..ec21cf06b 100644 --- a/spec/src/main/java/io/a2a/spec/Message.java +++ b/spec/src/main/java/io/a2a/spec/Message.java @@ -13,7 +13,7 @@ import io.a2a.util.Assert; /** - * An A2A message. + * Represents a single message in the conversation between a user and an agent. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/MessageSendConfiguration.java b/spec/src/main/java/io/a2a/spec/MessageSendConfiguration.java index f34af9dcf..9693b221b 100644 --- a/spec/src/main/java/io/a2a/spec/MessageSendConfiguration.java +++ b/spec/src/main/java/io/a2a/spec/MessageSendConfiguration.java @@ -8,10 +8,7 @@ import io.a2a.util.Assert; /** - * Represents the configuration of the message to be sent. - * - * If {@code blocking} is true, {@code pushNotification} is ignored. - * Both {@code blocking} and {@code pushNotification} are ignored in streaming interactions. + * Defines configuration options for a `message/send` or `message/stream` request. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) @@ -19,7 +16,6 @@ public record MessageSendConfiguration(List acceptedOutputModes, Integer PushNotificationConfig pushNotification, boolean blocking) { public MessageSendConfiguration { - Assert.checkNotNullParam("acceptedOutputModes", acceptedOutputModes); if (historyLength != null && historyLength < 0) { throw new IllegalArgumentException("Invalid history length"); } diff --git a/spec/src/main/java/io/a2a/spec/MessageSendParams.java b/spec/src/main/java/io/a2a/spec/MessageSendParams.java index a217539b1..7cba6f1ae 100644 --- a/spec/src/main/java/io/a2a/spec/MessageSendParams.java +++ b/spec/src/main/java/io/a2a/spec/MessageSendParams.java @@ -7,7 +7,8 @@ import io.a2a.util.Assert; /** - * Used to specify parameters when creating a message. + * Defines the parameters for a request to send a message to an agent. This can be used + * to create a new task, continue an existing one, or restart a task. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/MethodNotFoundError.java b/spec/src/main/java/io/a2a/spec/MethodNotFoundError.java index a8d9d9289..5a46b336f 100644 --- a/spec/src/main/java/io/a2a/spec/MethodNotFoundError.java +++ b/spec/src/main/java/io/a2a/spec/MethodNotFoundError.java @@ -7,6 +7,9 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +/** + * An error indicating that the requested method does not exist or is not available. + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public class MethodNotFoundError extends JSONRPCError { diff --git a/spec/src/main/java/io/a2a/spec/MutualTLSSecurityScheme.java b/spec/src/main/java/io/a2a/spec/MutualTLSSecurityScheme.java new file mode 100644 index 000000000..78f389f38 --- /dev/null +++ b/spec/src/main/java/io/a2a/spec/MutualTLSSecurityScheme.java @@ -0,0 +1,46 @@ +package io.a2a.spec; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Defines a security scheme using mTLS authentication. + */ +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonIgnoreProperties(ignoreUnknown = true) +public final class MutualTLSSecurityScheme implements SecurityScheme { + + public static final String MUTUAL_TLS = "mutualTLS"; + private final String description; + private final String type; + + public MutualTLSSecurityScheme(String description) { + this(description, MUTUAL_TLS); + } + + public MutualTLSSecurityScheme() { + this(null, MUTUAL_TLS); + } + + @JsonCreator + public MutualTLSSecurityScheme(@JsonProperty("description") String description, + @JsonProperty("type") String type) { + if (!type.equals(MUTUAL_TLS)) { + throw new IllegalArgumentException("Invalid type for MutualTLSSecurityScheme"); + } + this.description = description; + this.type = type; + } + + @Override + public String getDescription() { + return description; + } + + public String getType() { + return type; + } + +} diff --git a/spec/src/main/java/io/a2a/spec/NonStreamingJSONRPCRequest.java b/spec/src/main/java/io/a2a/spec/NonStreamingJSONRPCRequest.java index 1c0a696e7..f3ac7d2cb 100644 --- a/spec/src/main/java/io/a2a/spec/NonStreamingJSONRPCRequest.java +++ b/spec/src/main/java/io/a2a/spec/NonStreamingJSONRPCRequest.java @@ -12,5 +12,6 @@ @JsonDeserialize(using = NonStreamingJSONRPCRequestDeserializer.class) public abstract sealed class NonStreamingJSONRPCRequest extends JSONRPCRequest permits GetTaskRequest, CancelTaskRequest, SetTaskPushNotificationConfigRequest, GetTaskPushNotificationConfigRequest, - SendMessageRequest, DeleteTaskPushNotificationConfigRequest, ListTaskPushNotificationConfigRequest { + SendMessageRequest, DeleteTaskPushNotificationConfigRequest, ListTaskPushNotificationConfigRequest, + GetAuthenticatedExtendedCardRequest { } diff --git a/spec/src/main/java/io/a2a/spec/NonStreamingJSONRPCRequestDeserializer.java b/spec/src/main/java/io/a2a/spec/NonStreamingJSONRPCRequestDeserializer.java index c97c524c5..37366b9b7 100644 --- a/spec/src/main/java/io/a2a/spec/NonStreamingJSONRPCRequestDeserializer.java +++ b/spec/src/main/java/io/a2a/spec/NonStreamingJSONRPCRequestDeserializer.java @@ -48,6 +48,9 @@ public NonStreamingJSONRPCRequest deserialize(JsonParser jsonParser, Deserial case DeleteTaskPushNotificationConfigRequest.METHOD: return new DeleteTaskPushNotificationConfigRequest(jsonrpc, id, method, getAndValidateParams(paramsNode, jsonParser, treeNode, DeleteTaskPushNotificationConfigParams.class)); + case GetAuthenticatedExtendedCardRequest.METHOD: + return new GetAuthenticatedExtendedCardRequest(jsonrpc, id, method, + getAndValidateParams(paramsNode, jsonParser, treeNode, Void.class)); default: throw new MethodNotFoundJsonMappingException("Invalid method", getIdIfPossible(treeNode, jsonParser)); } diff --git a/spec/src/main/java/io/a2a/spec/OAuth2SecurityScheme.java b/spec/src/main/java/io/a2a/spec/OAuth2SecurityScheme.java index 10141ffb7..fd5c746a1 100644 --- a/spec/src/main/java/io/a2a/spec/OAuth2SecurityScheme.java +++ b/spec/src/main/java/io/a2a/spec/OAuth2SecurityScheme.java @@ -8,7 +8,7 @@ import io.a2a.util.Assert; /** - * Represents an OAuth2 security scheme. + * Defines a security scheme using OAuth 2.0. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) @@ -18,20 +18,22 @@ public final class OAuth2SecurityScheme implements SecurityScheme { private final OAuthFlows flows; private final String description; private final String type; + private final String oauth2MetadataUrl; - public OAuth2SecurityScheme(OAuthFlows flows, String description) { - this(flows, description, OAUTH2); + public OAuth2SecurityScheme(OAuthFlows flows, String description, String oauth2MetadataUrl) { + this(flows, description, oauth2MetadataUrl, OAUTH2); } @JsonCreator public OAuth2SecurityScheme(@JsonProperty("flows") OAuthFlows flows, @JsonProperty("description") String description, - @JsonProperty("type") String type) { + @JsonProperty("oauth2MetadataUrl") String oauth2MetadataUrl, @JsonProperty("type") String type) { Assert.checkNotNullParam("flows", flows); if (!type.equals(OAUTH2)) { throw new IllegalArgumentException("Invalid type for OAuth2SecurityScheme"); } this.flows = flows; this.description = description; + this.oauth2MetadataUrl = oauth2MetadataUrl; this.type = type; } @@ -48,9 +50,14 @@ public String getType() { return type; } + public String getOauth2MetadataUrl() { + return oauth2MetadataUrl; + } + public static class Builder { private OAuthFlows flows; private String description; + private String oauth2MetadataUrl; public Builder flows(OAuthFlows flows) { this.flows = flows; @@ -62,8 +69,13 @@ public Builder description(String description) { return this; } + public Builder oauth2MetadataUrl(String oauth2MetadataUrl) { + this.oauth2MetadataUrl = oauth2MetadataUrl; + return this; + } + public OAuth2SecurityScheme build() { - return new OAuth2SecurityScheme(flows, description); + return new OAuth2SecurityScheme(flows, description, oauth2MetadataUrl); } } } diff --git a/spec/src/main/java/io/a2a/spec/OAuthFlows.java b/spec/src/main/java/io/a2a/spec/OAuthFlows.java index fcd89bc3d..8c5015893 100644 --- a/spec/src/main/java/io/a2a/spec/OAuthFlows.java +++ b/spec/src/main/java/io/a2a/spec/OAuthFlows.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; /** - * Allows configuration of the supported OAuth Flows. + * Defines the configuration for the supported OAuth 2.0 flows. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/OpenIdConnectSecurityScheme.java b/spec/src/main/java/io/a2a/spec/OpenIdConnectSecurityScheme.java index f8f059792..26a07d67a 100644 --- a/spec/src/main/java/io/a2a/spec/OpenIdConnectSecurityScheme.java +++ b/spec/src/main/java/io/a2a/spec/OpenIdConnectSecurityScheme.java @@ -6,7 +6,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; /** - * Represents an OpenID Connect security scheme. + * Defines a security scheme using OpenID Connect. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/PasswordOAuthFlow.java b/spec/src/main/java/io/a2a/spec/PasswordOAuthFlow.java index a42e74942..424a4817f 100644 --- a/spec/src/main/java/io/a2a/spec/PasswordOAuthFlow.java +++ b/spec/src/main/java/io/a2a/spec/PasswordOAuthFlow.java @@ -8,7 +8,7 @@ import io.a2a.util.Assert; /** - * Configuration for the OAuth Resource Owner Password flow. + * Defines configuration details for the OAuth 2.0 Resource Owner Password flow. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/PushNotificationAuthenticationInfo.java b/spec/src/main/java/io/a2a/spec/PushNotificationAuthenticationInfo.java index b5b2bacd2..1ef29ccd4 100644 --- a/spec/src/main/java/io/a2a/spec/PushNotificationAuthenticationInfo.java +++ b/spec/src/main/java/io/a2a/spec/PushNotificationAuthenticationInfo.java @@ -7,7 +7,7 @@ import io.a2a.util.Assert; /** - * Defines authentication details for push notifications. + * Defines authentication details for a push notification endpoint. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/PushNotificationConfig.java b/spec/src/main/java/io/a2a/spec/PushNotificationConfig.java index 34270637f..7d577ffdb 100644 --- a/spec/src/main/java/io/a2a/spec/PushNotificationConfig.java +++ b/spec/src/main/java/io/a2a/spec/PushNotificationConfig.java @@ -5,7 +5,7 @@ import io.a2a.util.Assert; /** - * Represents a push notification. + * Defines the configuration for setting up push notifications for task updates. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/PushNotificationNotSupportedError.java b/spec/src/main/java/io/a2a/spec/PushNotificationNotSupportedError.java index d639b7bab..c618e2b78 100644 --- a/spec/src/main/java/io/a2a/spec/PushNotificationNotSupportedError.java +++ b/spec/src/main/java/io/a2a/spec/PushNotificationNotSupportedError.java @@ -7,6 +7,9 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +/** + * An A2A-specific error indicating that the agent does not support push notifications. + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public class PushNotificationNotSupportedError extends JSONRPCError { diff --git a/spec/src/main/java/io/a2a/spec/SecurityScheme.java b/spec/src/main/java/io/a2a/spec/SecurityScheme.java index 5003d01aa..37895d146 100644 --- a/spec/src/main/java/io/a2a/spec/SecurityScheme.java +++ b/spec/src/main/java/io/a2a/spec/SecurityScheme.java @@ -15,9 +15,15 @@ @JsonSubTypes.Type(value = APIKeySecurityScheme.class, name = API_KEY), @JsonSubTypes.Type(value = HTTPAuthSecurityScheme.class, name = HTTPAuthSecurityScheme.HTTP), @JsonSubTypes.Type(value = OAuth2SecurityScheme.class, name = OAuth2SecurityScheme.OAUTH2), - @JsonSubTypes.Type(value = OpenIdConnectSecurityScheme.class, name = OpenIdConnectSecurityScheme.OPENID_CONNECT) + @JsonSubTypes.Type(value = OpenIdConnectSecurityScheme.class, name = OpenIdConnectSecurityScheme.OPENID_CONNECT), + @JsonSubTypes.Type(value = MutualTLSSecurityScheme.class, name = MutualTLSSecurityScheme.MUTUAL_TLS) }) -public sealed interface SecurityScheme permits APIKeySecurityScheme, HTTPAuthSecurityScheme, OAuth2SecurityScheme, OpenIdConnectSecurityScheme { +/** + * Defines a security scheme that can be used to secure an agent's endpoints. + * This is a discriminated union type based on the OpenAPI 3.0 Security Scheme Object. + */ +public sealed interface SecurityScheme permits APIKeySecurityScheme, HTTPAuthSecurityScheme, OAuth2SecurityScheme, + OpenIdConnectSecurityScheme, MutualTLSSecurityScheme { String getDescription(); } diff --git a/spec/src/main/java/io/a2a/spec/Task.java b/spec/src/main/java/io/a2a/spec/Task.java index 86c92473e..00f757f31 100644 --- a/spec/src/main/java/io/a2a/spec/Task.java +++ b/spec/src/main/java/io/a2a/spec/Task.java @@ -11,7 +11,7 @@ import io.a2a.util.Assert; /** - * A central unit of work. + * Represents a single, stateful operation or conversation between a client and an agent. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/TaskArtifactUpdateEvent.java b/spec/src/main/java/io/a2a/spec/TaskArtifactUpdateEvent.java index 49485577b..03269bf33 100644 --- a/spec/src/main/java/io/a2a/spec/TaskArtifactUpdateEvent.java +++ b/spec/src/main/java/io/a2a/spec/TaskArtifactUpdateEvent.java @@ -9,7 +9,8 @@ import io.a2a.util.Assert; /** - * A task artifact update event. + * An event sent by the agent to notify the client that an artifact has been + * generated or updated. This is typically used in streaming models. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/TaskIdParams.java b/spec/src/main/java/io/a2a/spec/TaskIdParams.java index 816550eb9..237fe727a 100644 --- a/spec/src/main/java/io/a2a/spec/TaskIdParams.java +++ b/spec/src/main/java/io/a2a/spec/TaskIdParams.java @@ -7,7 +7,7 @@ import io.a2a.util.Assert; /** - * Task id parameters. + * Defines parameters containing a task ID, used for simple task operations. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/TaskNotCancelableError.java b/spec/src/main/java/io/a2a/spec/TaskNotCancelableError.java index aa40a81d3..eb8668140 100644 --- a/spec/src/main/java/io/a2a/spec/TaskNotCancelableError.java +++ b/spec/src/main/java/io/a2a/spec/TaskNotCancelableError.java @@ -7,6 +7,9 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +/** + * An A2A-specific error indicating that the task is in a state where it cannot be canceled. + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public class TaskNotCancelableError extends JSONRPCError { diff --git a/spec/src/main/java/io/a2a/spec/TaskNotFoundError.java b/spec/src/main/java/io/a2a/spec/TaskNotFoundError.java index 26ee264e3..c21998d2d 100644 --- a/spec/src/main/java/io/a2a/spec/TaskNotFoundError.java +++ b/spec/src/main/java/io/a2a/spec/TaskNotFoundError.java @@ -7,6 +7,9 @@ import static io.a2a.util.Utils.defaultIfNull; +/** + * An A2A-specific error indicating that the requested task ID was not found. + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public class TaskNotFoundError extends JSONRPCError { diff --git a/spec/src/main/java/io/a2a/spec/TaskPushNotificationConfig.java b/spec/src/main/java/io/a2a/spec/TaskPushNotificationConfig.java index 0e4163212..4cda7a8f3 100644 --- a/spec/src/main/java/io/a2a/spec/TaskPushNotificationConfig.java +++ b/spec/src/main/java/io/a2a/spec/TaskPushNotificationConfig.java @@ -5,7 +5,7 @@ import io.a2a.util.Assert; /** - * Task push notification configuration. + * A container associating a push notification configuration with a specific task. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/TaskQueryParams.java b/spec/src/main/java/io/a2a/spec/TaskQueryParams.java index 2587e5fb5..eb9892fe2 100644 --- a/spec/src/main/java/io/a2a/spec/TaskQueryParams.java +++ b/spec/src/main/java/io/a2a/spec/TaskQueryParams.java @@ -7,12 +7,13 @@ import io.a2a.util.Assert; /** - * Task query parameters. + * Defines parameters for querying a task, with an option to limit history length. * * @param id the ID for the task to be queried * @param historyLength the maximum number of items of history for the task to include in the response * @param metadata additional properties */ + @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public record TaskQueryParams(String id, Integer historyLength, Map metadata) { diff --git a/spec/src/main/java/io/a2a/spec/TaskState.java b/spec/src/main/java/io/a2a/spec/TaskState.java index 30d3c1a23..b2d296980 100644 --- a/spec/src/main/java/io/a2a/spec/TaskState.java +++ b/spec/src/main/java/io/a2a/spec/TaskState.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonValue; /** - * Represents the state of a task. + * Defines the lifecycle states of a Task. */ public enum TaskState { SUBMITTED("submitted"), diff --git a/spec/src/main/java/io/a2a/spec/TaskStatus.java b/spec/src/main/java/io/a2a/spec/TaskStatus.java index 2befdfcbf..d41455d04 100644 --- a/spec/src/main/java/io/a2a/spec/TaskStatus.java +++ b/spec/src/main/java/io/a2a/spec/TaskStatus.java @@ -9,7 +9,7 @@ import io.a2a.util.Assert; /** - * Represents the status of a task. + * Represents the status of a task at a specific point in time. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/TaskStatusUpdateEvent.java b/spec/src/main/java/io/a2a/spec/TaskStatusUpdateEvent.java index 7a44480da..21726d607 100644 --- a/spec/src/main/java/io/a2a/spec/TaskStatusUpdateEvent.java +++ b/spec/src/main/java/io/a2a/spec/TaskStatusUpdateEvent.java @@ -9,7 +9,8 @@ import io.a2a.util.Assert; /** - * A task status update event. + * An event sent by the agent to notify the client of a change in a task's status. + * This is typically used in streaming or subscription models. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/TextPart.java b/spec/src/main/java/io/a2a/spec/TextPart.java index 1b62cf747..be0a4b927 100644 --- a/spec/src/main/java/io/a2a/spec/TextPart.java +++ b/spec/src/main/java/io/a2a/spec/TextPart.java @@ -9,7 +9,7 @@ import io.a2a.util.Assert; /** - * A fundamental text unit of an Artifact or Message. + * Represents a text segment within a message or artifact. */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/spec/src/main/java/io/a2a/spec/TransportProtocol.java b/spec/src/main/java/io/a2a/spec/TransportProtocol.java new file mode 100644 index 000000000..289e9f5de --- /dev/null +++ b/spec/src/main/java/io/a2a/spec/TransportProtocol.java @@ -0,0 +1,38 @@ +package io.a2a.spec; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Supported A2A transport protocols. + */ +public enum TransportProtocol { + JSONRPC("JSONRPC"), + GRPC("GRPC"), + HTTP_JSON("HTTP+JSON"); + + private final String transport; + + TransportProtocol(String transport) { + this.transport = transport; + } + + @JsonValue + public String asString() { + return transport; + } + + @JsonCreator + public static TransportProtocol fromString(String transport) { + switch (transport) { + case "JSONRPC": + return JSONRPC; + case "GRPC": + return GRPC; + case "HTTP+JSON": + return HTTP_JSON; + default: + throw new IllegalArgumentException("Invalid transport: " + transport); + } + } +} \ No newline at end of file diff --git a/spec/src/main/java/io/a2a/spec/UnsupportedOperationError.java b/spec/src/main/java/io/a2a/spec/UnsupportedOperationError.java index d5ee0fb44..9fe055e9c 100644 --- a/spec/src/main/java/io/a2a/spec/UnsupportedOperationError.java +++ b/spec/src/main/java/io/a2a/spec/UnsupportedOperationError.java @@ -7,6 +7,9 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +/** + * An A2A-specific error indicating that the requested operation is not supported by the agent. + */ @JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonIgnoreProperties(ignoreUnknown = true) public class UnsupportedOperationError extends JSONRPCError { diff --git a/tck/pom.xml b/tck/pom.xml index 5272c1a1c..e03ef70da 100644 --- a/tck/pom.xml +++ b/tck/pom.xml @@ -7,7 +7,7 @@ io.github.a2asdk a2a-java-sdk-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT a2a-tck-server @@ -21,6 +21,11 @@ a2a-java-sdk-reference-jsonrpc ${project.version} + + io.github.a2asdk + a2a-java-sdk-reference-grpc + ${project.version} + io.quarkus quarkus-rest-jackson @@ -55,4 +60,4 @@ - \ No newline at end of file + diff --git a/tck/src/main/java/io/a2a/tck/server/AgentCardProducer.java b/tck/src/main/java/io/a2a/tck/server/AgentCardProducer.java index 610443ac8..54c9654da 100644 --- a/tck/src/main/java/io/a2a/tck/server/AgentCardProducer.java +++ b/tck/src/main/java/io/a2a/tck/server/AgentCardProducer.java @@ -1,5 +1,6 @@ package io.a2a.tck.server; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -9,7 +10,9 @@ import io.a2a.server.PublicAgentCard; import io.a2a.spec.AgentCapabilities; import io.a2a.spec.AgentCard; +import io.a2a.spec.AgentInterface; import io.a2a.spec.AgentSkill; +import io.a2a.spec.TransportProtocol; @ApplicationScoped public class AgentCardProducer { @@ -37,7 +40,10 @@ public AgentCard agentCard() { .tags(Collections.singletonList("hello world")) .examples(List.of("hi", "hello world")) .build())) - .protocolVersion("0.2.5") + .protocolVersion("0.3.0") + .additionalInterfaces(List.of( + new AgentInterface(TransportProtocol.JSONRPC.asString(), "http://localhost:9999"), + new AgentInterface(TransportProtocol.GRPC.asString(), "http://localhost:9000"))) .build(); } } diff --git a/tck/src/main/resources/application.properties b/tck/src/main/resources/application.properties index a2452b339..e850dd2f2 100644 --- a/tck/src/main/resources/application.properties +++ b/tck/src/main/resources/application.properties @@ -1 +1 @@ -%dev.quarkus.http.port=9999 \ No newline at end of file +%dev.quarkus.http.port=9999 diff --git a/tests/server-common/pom.xml b/tests/server-common/pom.xml index 831dcc86c..5b1cc3d1e 100644 --- a/tests/server-common/pom.xml +++ b/tests/server-common/pom.xml @@ -7,7 +7,7 @@ io.github.a2asdk a2a-java-sdk-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT ../../pom.xml a2a-java-sdk-tests-server-common diff --git a/tests/server-common/src/test/java/io/a2a/server/apps/common/AbstractA2AServerTest.java b/tests/server-common/src/test/java/io/a2a/server/apps/common/AbstractA2AServerTest.java index 3671da130..481767a2e 100644 --- a/tests/server-common/src/test/java/io/a2a/server/apps/common/AbstractA2AServerTest.java +++ b/tests/server-common/src/test/java/io/a2a/server/apps/common/AbstractA2AServerTest.java @@ -34,10 +34,13 @@ import io.a2a.spec.A2AServerException; import io.a2a.spec.AgentCard; import io.a2a.spec.Artifact; +import io.a2a.spec.AuthenticatedExtendedCardNotConfiguredError; import io.a2a.spec.CancelTaskRequest; import io.a2a.spec.CancelTaskResponse; import io.a2a.spec.DeleteTaskPushNotificationConfigResponse; import io.a2a.spec.Event; +import io.a2a.spec.GetAuthenticatedExtendedCardRequest; +import io.a2a.spec.GetAuthenticatedExtendedCardResponse; import io.a2a.spec.GetTaskPushNotificationConfigParams; import io.a2a.spec.GetTaskPushNotificationConfigRequest; import io.a2a.spec.GetTaskPushNotificationConfigResponse; @@ -425,7 +428,7 @@ public void testGetAgentCard() { AgentCard agentCard = given() .contentType(MediaType.APPLICATION_JSON) .when() - .get("/.well-known/agent.json") + .get("/.well-known/agent-card.json") .then() .statusCode(200) .extract() @@ -444,13 +447,20 @@ public void testGetAgentCard() { @Test public void testGetExtendAgentCardNotSupported() { - given() + GetAuthenticatedExtendedCardRequest request = new GetAuthenticatedExtendedCardRequest("1"); + GetAuthenticatedExtendedCardResponse response = given() .contentType(MediaType.APPLICATION_JSON) + .body(request) .when() - .get("/agent/authenticatedExtendedCard") + .post("/") .then() - .statusCode(404) - .body("error", equalTo("Extended agent card not supported or not enabled.")); + .statusCode(200) + .extract() + .as(GetAuthenticatedExtendedCardResponse.class); + assertEquals("1", response.getId()); + assertInstanceOf(JSONRPCError.class, response.getError()); + assertEquals(new AuthenticatedExtendedCardNotConfiguredError().getCode(), response.getError().getCode()); + assertNull(response.getResult()); } @Test diff --git a/transport/grpc/pom.xml b/transport/grpc/pom.xml index 982ae3b8e..93ec2a095 100644 --- a/transport/grpc/pom.xml +++ b/transport/grpc/pom.xml @@ -7,7 +7,7 @@ io.github.a2asdk a2a-java-sdk-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT ../../pom.xml a2a-java-sdk-transport-grpc diff --git a/transport/grpc/src/main/java/io/a2a/grpc/handler/GrpcHandler.java b/transport/grpc/src/main/java/io/a2a/grpc/handler/GrpcHandler.java index 15aa84209..69f9d2c1d 100644 --- a/transport/grpc/src/main/java/io/a2a/grpc/handler/GrpcHandler.java +++ b/transport/grpc/src/main/java/io/a2a/grpc/handler/GrpcHandler.java @@ -3,6 +3,8 @@ import static io.a2a.grpc.utils.ProtoUtils.FromProto; import static io.a2a.grpc.utils.ProtoUtils.ToProto; +import jakarta.enterprise.inject.Vetoed; + import java.util.HashMap; import java.util.List; import java.util.Map; @@ -43,6 +45,7 @@ import io.grpc.Status; import io.grpc.stub.StreamObserver; +@Vetoed public abstract class GrpcHandler extends A2AServiceGrpc.A2AServiceImplBase { // Hook so testing can wait until streaming subscriptions are established. diff --git a/transport/grpc/src/main/resources/META-INF/beans.xml b/transport/grpc/src/main/resources/META-INF/beans.xml index be7990041..9b2940fc2 100644 --- a/transport/grpc/src/main/resources/META-INF/beans.xml +++ b/transport/grpc/src/main/resources/META-INF/beans.xml @@ -2,5 +2,5 @@ + bean-discovery-mode="annotated"> \ No newline at end of file diff --git a/transport/jsonrpc/pom.xml b/transport/jsonrpc/pom.xml index b66e3b1f5..15eecd06e 100644 --- a/transport/jsonrpc/pom.xml +++ b/transport/jsonrpc/pom.xml @@ -7,7 +7,7 @@ io.github.a2asdk a2a-java-sdk-parent - 0.2.6.Beta1-SNAPSHOT + 0.3.0.Beta1-SNAPSHOT ../../pom.xml a2a-java-sdk-transport-jsonrpc diff --git a/transport/jsonrpc/src/main/java/io/a2a/jsonrpc/handler/JSONRPCHandler.java b/transport/jsonrpc/src/main/java/io/a2a/jsonrpc/handler/JSONRPCHandler.java index b2928dfd5..e4e11f294 100644 --- a/transport/jsonrpc/src/main/java/io/a2a/jsonrpc/handler/JSONRPCHandler.java +++ b/transport/jsonrpc/src/main/java/io/a2a/jsonrpc/handler/JSONRPCHandler.java @@ -2,20 +2,25 @@ import static io.a2a.server.util.async.AsyncUtils.createTubeConfig; import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Instance; import jakarta.inject.Inject; import java.util.List; import java.util.concurrent.Flow; +import io.a2a.server.ExtendedAgentCard; import io.a2a.server.PublicAgentCard; import io.a2a.server.ServerCallContext; import io.a2a.server.requesthandlers.RequestHandler; import io.a2a.spec.AgentCard; +import io.a2a.spec.AuthenticatedExtendedCardNotConfiguredError; import io.a2a.spec.CancelTaskRequest; import io.a2a.spec.CancelTaskResponse; import io.a2a.spec.DeleteTaskPushNotificationConfigRequest; import io.a2a.spec.DeleteTaskPushNotificationConfigResponse; import io.a2a.spec.EventKind; +import io.a2a.spec.GetAuthenticatedExtendedCardRequest; +import io.a2a.spec.GetAuthenticatedExtendedCardResponse; import io.a2a.spec.GetTaskPushNotificationConfigRequest; import io.a2a.spec.GetTaskPushNotificationConfigResponse; import io.a2a.spec.GetTaskRequest; @@ -43,14 +48,23 @@ public class JSONRPCHandler { private AgentCard agentCard; + private Instance extendedAgentCard; private RequestHandler requestHandler; protected JSONRPCHandler() { } @Inject + public JSONRPCHandler(@PublicAgentCard AgentCard agentCard, @ExtendedAgentCard Instance extendedAgentCard, + RequestHandler requestHandler) { + this.agentCard = agentCard; + this.extendedAgentCard = extendedAgentCard; + this.requestHandler = requestHandler; + } + public JSONRPCHandler(@PublicAgentCard AgentCard agentCard, RequestHandler requestHandler) { this.agentCard = agentCard; + this.extendedAgentCard = null; this.requestHandler = requestHandler; } @@ -202,6 +216,22 @@ public DeleteTaskPushNotificationConfigResponse deletePushNotificationConfig( } } + // TODO: Add authentication (https://github.com/a2aproject/a2a-java/issues/77) + public GetAuthenticatedExtendedCardResponse onGetAuthenticatedExtendedCardRequest( + GetAuthenticatedExtendedCardRequest request, ServerCallContext context) { + if ( !agentCard.supportsAuthenticatedExtendedCard() || !extendedAgentCard.isResolvable()) { + return new GetAuthenticatedExtendedCardResponse(request.getId(), + new AuthenticatedExtendedCardNotConfiguredError()); + } + try { + return new GetAuthenticatedExtendedCardResponse(request.getId(), extendedAgentCard.get()); + } catch (JSONRPCError e) { + return new GetAuthenticatedExtendedCardResponse(request.getId(), e); + } catch (Throwable t) { + return new GetAuthenticatedExtendedCardResponse(request.getId(), new InternalError(t.getMessage())); + } + } + public AgentCard getAgentCard() { return agentCard; } diff --git a/transport/jsonrpc/src/test/java/io/a2a/jsonrpc/handler/JSONRPCHandlerTest.java b/transport/jsonrpc/src/test/java/io/a2a/jsonrpc/handler/JSONRPCHandlerTest.java index 070df7aa1..a645c9b37 100644 --- a/transport/jsonrpc/src/test/java/io/a2a/jsonrpc/handler/JSONRPCHandlerTest.java +++ b/transport/jsonrpc/src/test/java/io/a2a/jsonrpc/handler/JSONRPCHandlerTest.java @@ -1,5 +1,9 @@ package io.a2a.jsonrpc.handler; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNull; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -19,12 +23,15 @@ import io.a2a.server.tasks.TaskUpdater; import io.a2a.spec.AgentCard; import io.a2a.spec.Artifact; +import io.a2a.spec.AuthenticatedExtendedCardNotConfiguredError; import io.a2a.spec.CancelTaskRequest; import io.a2a.spec.CancelTaskResponse; import io.a2a.spec.DeleteTaskPushNotificationConfigParams; import io.a2a.spec.DeleteTaskPushNotificationConfigRequest; import io.a2a.spec.DeleteTaskPushNotificationConfigResponse; import io.a2a.spec.Event; +import io.a2a.spec.GetAuthenticatedExtendedCardRequest; +import io.a2a.spec.GetAuthenticatedExtendedCardResponse; import io.a2a.spec.GetTaskPushNotificationConfigParams; import io.a2a.spec.GetTaskPushNotificationConfigRequest; import io.a2a.spec.GetTaskPushNotificationConfigResponse; @@ -75,9 +82,9 @@ public void testOnGetTaskSuccess() throws Exception { taskStore.save(MINIMAL_TASK); GetTaskRequest request = new GetTaskRequest("1", new TaskQueryParams(MINIMAL_TASK.getId())); GetTaskResponse response = handler.onGetTask(request, callContext); - Assertions.assertEquals(request.getId(), response.getId()); + assertEquals(request.getId(), response.getId()); Assertions.assertSame(MINIMAL_TASK, response.getResult()); - Assertions.assertNull(response.getError()); + assertNull(response.getError()); } @Test @@ -85,9 +92,9 @@ public void testOnGetTaskNotFound() throws Exception { JSONRPCHandler handler = new JSONRPCHandler(CARD, requestHandler); GetTaskRequest request = new GetTaskRequest("1", new TaskQueryParams(MINIMAL_TASK.getId())); GetTaskResponse response = handler.onGetTask(request, callContext); - Assertions.assertEquals(request.getId(), response.getId()); - Assertions.assertInstanceOf(TaskNotFoundError.class, response.getError()); - Assertions.assertNull(response.getResult()); + assertEquals(request.getId(), response.getId()); + assertInstanceOf(TaskNotFoundError.class, response.getError()); + assertNull(response.getResult()); } @Test @@ -107,12 +114,12 @@ public void testOnCancelTaskSuccess() throws Exception { CancelTaskRequest request = new CancelTaskRequest("111", new TaskIdParams(MINIMAL_TASK.getId())); CancelTaskResponse response = handler.onCancelTask(request, callContext); - Assertions.assertNull(response.getError()); - Assertions.assertEquals(request.getId(), response.getId()); + assertNull(response.getError()); + assertEquals(request.getId(), response.getId()); Task task = response.getResult(); - Assertions.assertEquals(MINIMAL_TASK.getId(), task.getId()); - Assertions.assertEquals(MINIMAL_TASK.getContextId(), task.getContextId()); - Assertions.assertEquals(TaskState.CANCELED, task.getStatus().state()); + assertEquals(MINIMAL_TASK.getId(), task.getId()); + assertEquals(MINIMAL_TASK.getContextId(), task.getContextId()); + assertEquals(TaskState.CANCELED, task.getStatus().state()); } @Test @@ -126,9 +133,9 @@ public void testOnCancelTaskNotSupported() { CancelTaskRequest request = new CancelTaskRequest("1", new TaskIdParams(MINIMAL_TASK.getId())); CancelTaskResponse response = handler.onCancelTask(request, callContext); - Assertions.assertEquals(request.getId(), response.getId()); - Assertions.assertNull(response.getResult()); - Assertions.assertInstanceOf(UnsupportedOperationError.class, response.getError()); + assertEquals(request.getId(), response.getId()); + assertNull(response.getResult()); + assertInstanceOf(UnsupportedOperationError.class, response.getError()); } @Test @@ -136,9 +143,9 @@ public void testOnCancelTaskNotFound() { JSONRPCHandler handler = new JSONRPCHandler(CARD, requestHandler); CancelTaskRequest request = new CancelTaskRequest("1", new TaskIdParams(MINIMAL_TASK.getId())); CancelTaskResponse response = handler.onCancelTask(request, callContext); - Assertions.assertEquals(request.getId(), response.getId()); - Assertions.assertNull(response.getResult()); - Assertions.assertInstanceOf(TaskNotFoundError.class, response.getError()); + assertEquals(request.getId(), response.getId()); + assertNull(response.getResult()); + assertInstanceOf(TaskNotFoundError.class, response.getError()); } @Test @@ -153,7 +160,7 @@ public void testOnMessageNewMessageSuccess() { .build(); SendMessageRequest request = new SendMessageRequest("1", new MessageSendParams(message, null, null)); SendMessageResponse response = handler.onMessageSend(request, callContext); - Assertions.assertNull(response.getError()); + assertNull(response.getError()); // The Python implementation returns a Task here, but then again they are using hardcoded mocks and // bypassing the whole EventQueue. // If we were to send a Task in agentExecutorExecute EventConsumer.consumeAll() would not exit due to @@ -179,7 +186,7 @@ public void testOnMessageNewMessageSuccessMocks() { (mock, context) -> {Mockito.doReturn(ZeroPublisher.fromItems(MINIMAL_TASK)).when(mock).consumeAll();})){ response = handler.onMessageSend(request, callContext); } - Assertions.assertNull(response.getError()); + assertNull(response.getError()); Assertions.assertSame(MINIMAL_TASK, response.getResult()); } @@ -196,7 +203,7 @@ public void testOnMessageNewMessageWithExistingTaskSuccess() { .build(); SendMessageRequest request = new SendMessageRequest("1", new MessageSendParams(message, null, null)); SendMessageResponse response = handler.onMessageSend(request, callContext); - Assertions.assertNull(response.getError()); + assertNull(response.getError()); // The Python implementation returns a Task here, but then again they are using hardcoded mocks and // bypassing the whole EventQueue. // If we were to send a Task in agentExecutorExecute EventConsumer.consumeAll() would not exit due to @@ -223,7 +230,7 @@ public void testOnMessageNewMessageWithExistingTaskSuccessMocks() { Mockito.doReturn(ZeroPublisher.fromItems(MINIMAL_TASK)).when(mock).consumeAll();})){ response = handler.onMessageSend(request, callContext); } - Assertions.assertNull(response.getError()); + assertNull(response.getError()); Assertions.assertSame(MINIMAL_TASK, response.getResult()); } @@ -243,8 +250,8 @@ public void testOnMessageError() { SendMessageRequest request = new SendMessageRequest( "1", new MessageSendParams(message, null, null)); SendMessageResponse response = handler.onMessageSend(request, callContext); - Assertions.assertInstanceOf(UnsupportedOperationError.class, response.getError()); - Assertions.assertNull(response.getResult()); + assertInstanceOf(UnsupportedOperationError.class, response.getError()); + assertNull(response.getResult()); } @Test @@ -264,8 +271,8 @@ public void testOnMessageErrorMocks() { response = handler.onMessageSend(request, callContext); } - Assertions.assertInstanceOf(UnsupportedOperationError.class, response.getError()); - Assertions.assertNull(response.getResult()); + assertInstanceOf(UnsupportedOperationError.class, response.getError()); + assertNull(response.getResult()); } @Test @@ -319,7 +326,7 @@ public void onComplete() { // so there would be no more Events. // // See testOnMessageStreamNewMessageSuccessMocks() for a test more similar to the Python implementation - Assertions.assertEquals(1, results.size()); + assertEquals(1, results.size()); Assertions.assertSame(message, results.get(0)); } @@ -387,7 +394,7 @@ public void onComplete() { } }); - Assertions.assertEquals(events, results); + assertEquals(events, results); } @Test @@ -454,14 +461,14 @@ public void onComplete() { Task expected = new Task.Builder(task) .history(message) .build(); - Assertions.assertEquals(1, results.size()); + assertEquals(1, results.size()); StreamingEventKind receivedType = results.get(0); - Assertions.assertInstanceOf(Task.class, receivedType); + assertInstanceOf(Task.class, receivedType); Task received = (Task) receivedType; - Assertions.assertEquals(expected.getId(), received.getId()); - Assertions.assertEquals(expected.getContextId(), received.getContextId()); - Assertions.assertEquals(expected.getStatus(), received.getStatus()); - Assertions.assertEquals(expected.getHistory(), received.getHistory()); + assertEquals(expected.getId(), received.getId()); + assertEquals(expected.getContextId(), received.getContextId()); + assertEquals(expected.getStatus(), received.getStatus()); + assertEquals(expected.getHistory(), received.getHistory()); } @Test @@ -535,7 +542,7 @@ public void onComplete() { } }); - Assertions.assertEquals(events, results); + assertEquals(events, results); } @@ -574,7 +581,7 @@ public void testGetPushNotificationConfigSuccess() { TaskPushNotificationConfig expectedConfig = new TaskPushNotificationConfig(MINIMAL_TASK.getId(), new PushNotificationConfig.Builder().id(MINIMAL_TASK.getId()).url("http://example.com").build()); - Assertions.assertEquals(expectedConfig, getResponse.getResult()); + assertEquals(expectedConfig, getResponse.getResult()); } @Test @@ -612,7 +619,7 @@ public void testOnMessageStreamNewMessageSendPushNotificationSuccess() throws Ex new PushNotificationConfig.Builder().url("http://example.com").build()); SetTaskPushNotificationConfigRequest stpnRequest = new SetTaskPushNotificationConfigRequest("1", config); SetTaskPushNotificationConfigResponse stpnResponse = handler.setPushNotificationConfig(stpnRequest, callContext); - Assertions.assertNull(stpnResponse.getError()); + assertNull(stpnResponse.getError()); Message msg = new Message.Builder(MESSAGE) .taskId(MINIMAL_TASK.getId()) @@ -656,30 +663,30 @@ public void onComplete() { Assertions.assertTrue(latch.await(5, TimeUnit.SECONDS)); subscriptionRef.get().cancel(); - Assertions.assertEquals(3, results.size()); - Assertions.assertEquals(3, httpClient.tasks.size()); + assertEquals(3, results.size()); + assertEquals(3, httpClient.tasks.size()); Task curr = httpClient.tasks.get(0); - Assertions.assertEquals(MINIMAL_TASK.getId(), curr.getId()); - Assertions.assertEquals(MINIMAL_TASK.getContextId(), curr.getContextId()); - Assertions.assertEquals(MINIMAL_TASK.getStatus().state(), curr.getStatus().state()); - Assertions.assertEquals(0, curr.getArtifacts() == null ? 0 : curr.getArtifacts().size()); + assertEquals(MINIMAL_TASK.getId(), curr.getId()); + assertEquals(MINIMAL_TASK.getContextId(), curr.getContextId()); + assertEquals(MINIMAL_TASK.getStatus().state(), curr.getStatus().state()); + assertEquals(0, curr.getArtifacts() == null ? 0 : curr.getArtifacts().size()); curr = httpClient.tasks.get(1); - Assertions.assertEquals(MINIMAL_TASK.getId(), curr.getId()); - Assertions.assertEquals(MINIMAL_TASK.getContextId(), curr.getContextId()); - Assertions.assertEquals(MINIMAL_TASK.getStatus().state(), curr.getStatus().state()); - Assertions.assertEquals(1, curr.getArtifacts().size()); - Assertions.assertEquals(1, curr.getArtifacts().get(0).parts().size()); - Assertions.assertEquals("text", ((TextPart)curr.getArtifacts().get(0).parts().get(0)).getText()); + assertEquals(MINIMAL_TASK.getId(), curr.getId()); + assertEquals(MINIMAL_TASK.getContextId(), curr.getContextId()); + assertEquals(MINIMAL_TASK.getStatus().state(), curr.getStatus().state()); + assertEquals(1, curr.getArtifacts().size()); + assertEquals(1, curr.getArtifacts().get(0).parts().size()); + assertEquals("text", ((TextPart)curr.getArtifacts().get(0).parts().get(0)).getText()); curr = httpClient.tasks.get(2); - Assertions.assertEquals(MINIMAL_TASK.getId(), curr.getId()); - Assertions.assertEquals(MINIMAL_TASK.getContextId(), curr.getContextId()); - Assertions.assertEquals(TaskState.COMPLETED, curr.getStatus().state()); - Assertions.assertEquals(1, curr.getArtifacts().size()); - Assertions.assertEquals(1, curr.getArtifacts().get(0).parts().size()); - Assertions.assertEquals("text", ((TextPart)curr.getArtifacts().get(0).parts().get(0)).getText()); + assertEquals(MINIMAL_TASK.getId(), curr.getId()); + assertEquals(MINIMAL_TASK.getContextId(), curr.getContextId()); + assertEquals(TaskState.COMPLETED, curr.getStatus().state()); + assertEquals(1, curr.getArtifacts().size()); + assertEquals(1, curr.getArtifacts().get(0).parts().size()); + assertEquals("text", ((TextPart)curr.getArtifacts().get(0).parts().get(0)).getText()); } @Test @@ -708,7 +715,7 @@ public void testOnResubscribeExistingTaskSuccess() { handler.onMessageSend( new SendMessageRequest("1", new MessageSendParams(message, null, null)), callContext); - Assertions.assertNull(smr.getError()); + assertNull(smr.getError()); List results = new ArrayList<>(); @@ -742,7 +749,7 @@ public void onComplete() { // The Python implementation has several events emitted since it uses mocks. // // See testOnMessageStreamNewMessageExistingTaskSuccessMocks() for a test more similar to the Python implementation - Assertions.assertEquals(1, results.size()); + assertEquals(1, results.size()); } @@ -810,7 +817,7 @@ public void onComplete() { // The Python implementation has several events emitted since it uses mocks. // // See testOnMessageStreamNewMessageExistingTaskSuccessMocks() for a test more similar to the Python implementation - Assertions.assertEquals(events, results); + assertEquals(events, results); } @Test @@ -850,9 +857,9 @@ public void onComplete() { } }); - Assertions.assertEquals(1, results.size()); - Assertions.assertNull(results.get(0).getResult()); - Assertions.assertInstanceOf(TaskNotFoundError.class, results.get(0).getError()); + assertEquals(1, results.size()); + assertNull(results.get(0).getResult()); + assertInstanceOf(TaskNotFoundError.class, results.get(0).getError()); } @Test @@ -897,9 +904,9 @@ public void onComplete() { } }); - Assertions.assertEquals(1, results.size()); + assertEquals(1, results.size()); if (results.get(0).getError() != null && results.get(0).getError() instanceof InvalidRequestError ire) { - Assertions.assertEquals("Streaming is not supported by the agent", ire.getMessage()); + assertEquals("Streaming is not supported by the agent", ire.getMessage()); } else { Assertions.fail("Expected a response containing an error"); } @@ -943,9 +950,9 @@ public void onComplete() { } }); - Assertions.assertEquals(1, results.size()); + assertEquals(1, results.size()); if (results.get(0).getError() != null && results.get(0).getError() instanceof InvalidRequestError ire) { - Assertions.assertEquals("Streaming is not supported by the agent", ire.getMessage()); + assertEquals("Streaming is not supported by the agent", ire.getMessage()); } else { Assertions.fail("Expected a response containing an error"); } @@ -969,7 +976,7 @@ public void testPushNotificationsNotSupportedError() { .params(config) .build(); SetTaskPushNotificationConfigResponse response = handler.setPushNotificationConfig(request, callContext); - Assertions.assertInstanceOf(PushNotificationNotSupportedError.class, response.getError()); + assertInstanceOf(PushNotificationNotSupportedError.class, response.getError()); } @Test @@ -987,8 +994,8 @@ public void testOnGetPushNotificationNoPushNotifierConfig() { GetTaskPushNotificationConfigResponse response = handler.getPushNotificationConfig(request, callContext); Assertions.assertNotNull(response.getError()); - Assertions.assertInstanceOf(UnsupportedOperationError.class, response.getError()); - Assertions.assertEquals("This operation is not supported", response.getError().getMessage()); + assertInstanceOf(UnsupportedOperationError.class, response.getError()); + assertEquals("This operation is not supported", response.getError().getMessage()); } @Test @@ -1013,8 +1020,8 @@ public void testOnSetPushNotificationNoPushNotifierConfig() { .build(); SetTaskPushNotificationConfigResponse response = handler.setPushNotificationConfig(request, callContext); - Assertions.assertInstanceOf(UnsupportedOperationError.class, response.getError()); - Assertions.assertEquals("This operation is not supported", response.getError().getMessage()); + assertInstanceOf(UnsupportedOperationError.class, response.getError()); + assertEquals("This operation is not supported", response.getError().getMessage()); } @Test @@ -1028,7 +1035,7 @@ public void testOnMessageSendInternalError() { SendMessageRequest request = new SendMessageRequest("1", new MessageSendParams(MESSAGE, null, null)); SendMessageResponse response = handler.onMessageSend(request, callContext); - Assertions.assertInstanceOf(InternalError.class, response.getError()); + assertInstanceOf(InternalError.class, response.getError()); } @Test @@ -1072,8 +1079,8 @@ public void onComplete() { } }); - Assertions.assertEquals(1, results.size()); - Assertions.assertInstanceOf(InternalError.class, results.get(0).getError()); + assertEquals(1, results.size()); + assertInstanceOf(InternalError.class, results.get(0).getError()); } @Test @@ -1109,7 +1116,7 @@ public void testOnMessageSendErrorHandling() { response = handler.onMessageSend(request, callContext); } - Assertions.assertInstanceOf(UnsupportedOperationError.class, response.getError()); + assertInstanceOf(UnsupportedOperationError.class, response.getError()); } @@ -1124,7 +1131,7 @@ public void testOnMessageSendTaskIdMismatch() { SendMessageRequest request = new SendMessageRequest("1", new MessageSendParams(MESSAGE, null, null)); SendMessageResponse response = handler.onMessageSend(request, callContext); - Assertions.assertInstanceOf(InternalError.class, response.getError()); + assertInstanceOf(InternalError.class, response.getError()); } @@ -1169,9 +1176,9 @@ public void onComplete() { } }); - Assertions.assertNull(error.get()); - Assertions.assertEquals(1, results.size()); - Assertions.assertInstanceOf(InternalError.class, results.get(0).getError()); + assertNull(error.get()); + assertEquals(1, results.size()); + assertInstanceOf(InternalError.class, results.get(0).getError()); } @Test @@ -1195,9 +1202,9 @@ public void testListPushNotificationConfig() { new ListTaskPushNotificationConfigRequest("111", new ListTaskPushNotificationConfigParams(MINIMAL_TASK.getId())); ListTaskPushNotificationConfigResponse listResponse = handler.listPushNotificationConfig(listRequest, callContext); - Assertions.assertEquals("111", listResponse.getId()); - Assertions.assertEquals(1, listResponse.getResult().size()); - Assertions.assertEquals(taskPushConfig, listResponse.getResult().get(0)); + assertEquals("111", listResponse.getId()); + assertEquals(1, listResponse.getResult().size()); + assertEquals(taskPushConfig, listResponse.getResult().get(0)); } @Test @@ -1223,9 +1230,9 @@ public void testListPushNotificationConfigNotSupported() { ListTaskPushNotificationConfigResponse listResponse = handler.listPushNotificationConfig(listRequest, callContext); - Assertions.assertEquals("111", listResponse.getId()); - Assertions.assertNull(listResponse.getResult()); - Assertions.assertInstanceOf(PushNotificationNotSupportedError.class, listResponse.getError()); + assertEquals("111", listResponse.getId()); + assertNull(listResponse.getResult()); + assertInstanceOf(PushNotificationNotSupportedError.class, listResponse.getError()); } @Test @@ -1243,9 +1250,9 @@ public void testListPushNotificationConfigNoPushConfigStore() { ListTaskPushNotificationConfigResponse listResponse = handler.listPushNotificationConfig(listRequest, callContext); - Assertions.assertEquals("111", listResponse.getId()); - Assertions.assertNull(listResponse.getResult()); - Assertions.assertInstanceOf(UnsupportedOperationError.class, listResponse.getError()); + assertEquals("111", listResponse.getId()); + assertNull(listResponse.getResult()); + assertInstanceOf(UnsupportedOperationError.class, listResponse.getError()); } @Test @@ -1260,9 +1267,9 @@ public void testListPushNotificationConfigTaskNotFound() { ListTaskPushNotificationConfigResponse listResponse = handler.listPushNotificationConfig(listRequest, callContext); - Assertions.assertEquals("111", listResponse.getId()); - Assertions.assertNull(listResponse.getResult()); - Assertions.assertInstanceOf(TaskNotFoundError.class, listResponse.getError()); + assertEquals("111", listResponse.getId()); + assertNull(listResponse.getResult()); + assertInstanceOf(TaskNotFoundError.class, listResponse.getError()); } @Test @@ -1287,9 +1294,9 @@ public void testDeletePushNotificationConfig() { DeleteTaskPushNotificationConfigResponse deleteResponse = handler.deletePushNotificationConfig(deleteRequest, callContext); - Assertions.assertEquals("111", deleteResponse.getId()); - Assertions.assertNull(deleteResponse.getError()); - Assertions.assertNull(deleteResponse.getResult()); + assertEquals("111", deleteResponse.getId()); + assertNull(deleteResponse.getError()); + assertNull(deleteResponse.getResult()); } @Test @@ -1315,9 +1322,9 @@ public void testDeletePushNotificationConfigNotSupported() { DeleteTaskPushNotificationConfigResponse deleteResponse = handler.deletePushNotificationConfig(deleteRequest, callContext); - Assertions.assertEquals("111", deleteResponse.getId()); - Assertions.assertNull(deleteResponse.getResult()); - Assertions.assertInstanceOf(PushNotificationNotSupportedError.class, deleteResponse.getError()); + assertEquals("111", deleteResponse.getId()); + assertNull(deleteResponse.getResult()); + assertInstanceOf(PushNotificationNotSupportedError.class, deleteResponse.getError()); } @Test @@ -1344,9 +1351,19 @@ public void testDeletePushNotificationConfigNoPushConfigStore() { DeleteTaskPushNotificationConfigResponse deleteResponse = handler.deletePushNotificationConfig(deleteRequest, callContext); - Assertions.assertEquals("111", deleteResponse.getId()); - Assertions.assertNull(deleteResponse.getResult()); - Assertions.assertInstanceOf(UnsupportedOperationError.class, deleteResponse.getError()); + assertEquals("111", deleteResponse.getId()); + assertNull(deleteResponse.getResult()); + assertInstanceOf(UnsupportedOperationError.class, deleteResponse.getError()); + } + + @Test + public void testOnGetAuthenticatedExtendedAgentCard() throws Exception { + JSONRPCHandler handler = new JSONRPCHandler(CARD, requestHandler); + GetAuthenticatedExtendedCardRequest request = new GetAuthenticatedExtendedCardRequest("1"); + GetAuthenticatedExtendedCardResponse response = handler.onGetAuthenticatedExtendedCardRequest(request, callContext); + assertEquals(request.getId(), response.getId()); + assertInstanceOf(AuthenticatedExtendedCardNotConfiguredError.class, response.getError()); + assertNull(response.getResult()); } }