Skip to content

Commit 841ad4a

Browse files
committed
chore: add back tck modules
Copy the generated code from a2a-tck/sut/a2a-java Signed-off-by: Jeff Mesnil <jmesnil@ibm.com>
1 parent b835e9f commit 841ad4a

6 files changed

Lines changed: 297 additions & 10 deletions

File tree

‎.github/workflows/run-tck.yml‎

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,6 @@ jobs:
3838
cache: maven
3939
- name: Build a2a-java SDK
4040
run: mvn -B install -DskipTests
41-
- name: Extract a2a-java version
42-
id: extract-version
43-
run: |
44-
A2A_JAVA_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
45-
echo "version=$A2A_JAVA_VERSION" >> $GITHUB_OUTPUT
46-
echo "Detected a2a-java version: $A2A_JAVA_VERSION"
4741
- name: Checkout a2a-tck
4842
uses: actions/checkout@v6
4943
with:
@@ -59,12 +53,9 @@ jobs:
5953
pip install uv
6054
uv pip install -e .
6155
working-directory: a2a-tck
62-
- name: Generate a2a-java SUT
63-
run: A2A_JAVA_SDK_VERSION=${{ steps.extract-version.outputs.version }} make codegen-a2a-java-sut
64-
working-directory: a2a-tck
6556
- name: Start SUT
6657
run: mvn -B quarkus:dev -Dquarkus.console.enabled=false &
67-
working-directory: a2a-tck/sut/a2a-java
58+
working-directory: tck
6859
- name: Wait for SUT to start
6960
run: |
7061
URL="${{ env.SUT_URL }}/.well-known/agent-card.json"

‎pom.xml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,10 @@
605605
<module>boms/extras</module>
606606
<module>boms/reference</module>
607607
<module>boms/sdk</module>
608+
609+
<!-- TCK -->
610+
<module>tck</module>
611+
608612
</modules>
609613

610614
<profiles>

‎tck/pom.xml‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>org.a2aproject.sdk</groupId>
9+
<artifactId>a2a-java-sdk-parent</artifactId>
10+
<version>1.0.0.Beta2-SNAPSHOT</version>
11+
</parent>
12+
<artifactId>a2a-java-sdk-tck-sut</artifactId>
13+
<name>A2A Java SDK: SUT for TCK</name>
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>org.a2aproject.sdk</groupId>
18+
<artifactId>a2a-java-sdk-client</artifactId>
19+
</dependency>
20+
<dependency>
21+
<groupId>org.a2aproject.sdk</groupId>
22+
<artifactId>a2a-java-sdk-reference-jsonrpc</artifactId>
23+
</dependency>
24+
<dependency>
25+
<groupId>org.a2aproject.sdk</groupId>
26+
<artifactId>a2a-java-sdk-reference-grpc</artifactId>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.a2aproject.sdk</groupId>
30+
<artifactId>a2a-java-sdk-reference-rest</artifactId>
31+
</dependency>
32+
<dependency>
33+
<groupId>jakarta.enterprise</groupId>
34+
<artifactId>jakarta.enterprise.cdi-api</artifactId>
35+
<scope>provided</scope>
36+
</dependency>
37+
<dependency>
38+
<groupId>jakarta.ws.rs</groupId>
39+
<artifactId>jakarta.ws.rs-api</artifactId>
40+
</dependency>
41+
<dependency>
42+
<groupId>org.a2aproject.sdk</groupId>
43+
<artifactId>a2a-java-sdk-server-common</artifactId>
44+
</dependency>
45+
46+
</dependencies>
47+
48+
<build>
49+
<plugins>
50+
<plugin>
51+
<groupId>io.quarkus.platform</groupId>
52+
<artifactId>quarkus-maven-plugin</artifactId>
53+
<extensions>true</extensions>
54+
<executions>
55+
<execution>
56+
<goals>
57+
<goal>build</goal>
58+
<goal>generate-code</goal>
59+
<goal>generate-code-tests</goal>
60+
</goals>
61+
</execution>
62+
</executions>
63+
</plugin>
64+
</plugins>
65+
</build>
66+
</project>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package org.a2aproject.sdk.sut;
2+
3+
import java.util.List;
4+
5+
import jakarta.enterprise.context.ApplicationScoped;
6+
import jakarta.enterprise.inject.Produces;
7+
8+
import org.a2aproject.sdk.server.PublicAgentCard;
9+
import org.a2aproject.sdk.spec.AgentCapabilities;
10+
import org.a2aproject.sdk.spec.AgentCard;
11+
import org.a2aproject.sdk.spec.AgentInterface;
12+
import org.a2aproject.sdk.spec.AgentSkill;
13+
import org.a2aproject.sdk.spec.TransportProtocol;
14+
15+
/**
16+
* CDI producer for the TCK agent card.
17+
*
18+
* <p>Generated from Gherkin scenarios — do not edit by hand.
19+
*/
20+
@ApplicationScoped
21+
public class TckAgentCardProducer {
22+
23+
private static final String host = getEnvOrDefault("SUT_HOST", "localhost:9999");
24+
25+
@Produces
26+
@PublicAgentCard
27+
public AgentCard agentCard() {
28+
String sutJsonRpcUrl = String.format("http://%s", host);
29+
String sutRestUrl = sutJsonRpcUrl;
30+
String sutGrpcUrl = host;
31+
32+
return AgentCard.builder()
33+
.name("A2A Java SDK System Under Test (SUT)")
34+
.description("Auto-generated System Under Test for A2A TCK conformance")
35+
.version("1.0.0")
36+
.supportedInterfaces(List.of(
37+
new AgentInterface(TransportProtocol.JSONRPC.asString(), sutJsonRpcUrl),
38+
new AgentInterface(TransportProtocol.GRPC.asString(), sutGrpcUrl),
39+
new AgentInterface(TransportProtocol.HTTP_JSON.asString(), sutRestUrl)))
40+
.capabilities(AgentCapabilities.builder()
41+
.streaming(true)
42+
.pushNotifications(true)
43+
.build())
44+
.defaultInputModes(List.of("text"))
45+
.defaultOutputModes(List.of("text"))
46+
.skills(List.of(
47+
AgentSkill.builder()
48+
.id("tck")
49+
.name("TCK Conformance")
50+
.description("Handles TCK conformance test messages")
51+
.tags(List.of("tck"))
52+
.build()))
53+
.build();
54+
}
55+
56+
private static String getEnvOrDefault(String envVar, String defaultValue) {
57+
String value = System.getenv(envVar);
58+
return value == null || value.isBlank() ? defaultValue : value;
59+
}
60+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package org.a2aproject.sdk.sut;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
import jakarta.enterprise.context.ApplicationScoped;
7+
import jakarta.enterprise.inject.Produces;
8+
9+
import org.a2aproject.sdk.A2A;
10+
import org.a2aproject.sdk.server.agentexecution.AgentExecutor;
11+
import org.a2aproject.sdk.server.agentexecution.RequestContext;
12+
import org.a2aproject.sdk.server.tasks.AgentEmitter;
13+
import org.a2aproject.sdk.spec.A2AError;
14+
import org.a2aproject.sdk.spec.DataPart;
15+
import org.a2aproject.sdk.spec.FileWithBytes;
16+
import org.a2aproject.sdk.spec.FileWithUri;
17+
import org.a2aproject.sdk.spec.FilePart;
18+
import org.a2aproject.sdk.spec.TaskNotCancelableError;
19+
import org.a2aproject.sdk.spec.TextPart;
20+
21+
/**
22+
* CDI producer for the TCK agent executor.
23+
*
24+
* <p>Generated from Gherkin scenarios — do not edit by hand.
25+
*/
26+
@ApplicationScoped
27+
public class TckAgentExecutorProducer {
28+
29+
@Produces
30+
public AgentExecutor agentExecutor() {
31+
return new AgentExecutor() {
32+
@Override
33+
public void execute(RequestContext context, AgentEmitter emitter) throws A2AError {
34+
String messageId = context.getMessage().messageId();
35+
36+
if (messageId.startsWith("tck-stream-artifact-chunked")) {
37+
emitter.startWork();
38+
emitter.addArtifact(List.of(new TextPart("chunk-1 ")), null, null, null, true, false);
39+
emitter.addArtifact(List.of(new TextPart("chunk-2")), null, null, null, true, true);
40+
emitter.complete();
41+
return;
42+
}
43+
44+
if (messageId.startsWith("test-resubscribe-message-id")) {
45+
emitter.startWork();
46+
try { Thread.sleep(4000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
47+
emitter.complete();
48+
return;
49+
}
50+
51+
if (messageId.startsWith("tck-stream-artifact-text")) {
52+
emitter.startWork();
53+
emitter.addArtifact(List.of(new TextPart("Streamed text content")), null, null, null);
54+
emitter.complete();
55+
return;
56+
}
57+
58+
if (messageId.startsWith("tck-stream-artifact-file")) {
59+
emitter.startWork();
60+
emitter.addArtifact(List.of(new FilePart(new FileWithBytes("text/plain", "output.txt", "dGNr"))), null, null, null);
61+
emitter.complete();
62+
return;
63+
}
64+
65+
if (messageId.startsWith("tck-stream-ordering-001")) {
66+
emitter.startWork();
67+
emitter.addArtifact(List.of(new TextPart("Ordered output")), null, null, null);
68+
emitter.complete();
69+
return;
70+
}
71+
72+
if (messageId.startsWith("tck-artifact-file-url")) {
73+
emitter.addArtifact(List.of(new FilePart(new FileWithUri("text/plain", "output.txt", "https://example.com/output.txt"))), null, null, null);
74+
emitter.complete();
75+
return;
76+
}
77+
78+
if (messageId.startsWith("tck-message-response")) {
79+
emitter.sendMessage(List.of(new TextPart("Direct message response")));
80+
return;
81+
}
82+
83+
if (messageId.startsWith("tck-input-required")) {
84+
emitter.requiresInput();
85+
return;
86+
}
87+
88+
if (messageId.startsWith("tck-complete-task")) {
89+
emitter.complete(A2A.toAgentMessage("Hello from TCK"));
90+
return;
91+
}
92+
93+
if (messageId.startsWith("tck-artifact-text")) {
94+
emitter.addArtifact(List.of(new TextPart("Generated text content")), null, null, null);
95+
emitter.complete();
96+
return;
97+
}
98+
99+
if (messageId.startsWith("tck-artifact-file")) {
100+
emitter.addArtifact(List.of(new FilePart(new FileWithBytes("text/plain", "output.txt", "dGNr"))), null, null, null);
101+
emitter.complete();
102+
return;
103+
}
104+
105+
if (messageId.startsWith("tck-artifact-data")) {
106+
emitter.addArtifact(List.of(DataPart.fromJson("{\"key\": \"value\", \"count\": 42}")), null, null, null);
107+
emitter.complete();
108+
return;
109+
}
110+
111+
if (messageId.startsWith("tck-reject-task")) {
112+
throw new A2AError(-1, "rejected", null);
113+
}
114+
115+
if (messageId.startsWith("tck-stream-001")) {
116+
emitter.startWork();
117+
emitter.addArtifact(List.of(new TextPart("Stream hello from TCK")), null, null, null);
118+
emitter.complete();
119+
return;
120+
}
121+
122+
if (messageId.startsWith("tck-stream-002")) {
123+
emitter.complete();
124+
return;
125+
}
126+
127+
if (messageId.startsWith("tck-stream-003")) {
128+
emitter.startWork();
129+
emitter.addArtifact(List.of(new TextPart("Stream task lifecycle")), null, null, null);
130+
emitter.complete();
131+
return;
132+
}
133+
134+
// Default: complete the task with an echo response
135+
emitter.complete(A2A.toAgentMessage("Unhandled messageId prefix: " + messageId));
136+
}
137+
138+
@Override
139+
public void cancel(RequestContext context, AgentEmitter emitter) throws A2AError {
140+
emitter.cancel();
141+
}
142+
};
143+
}
144+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated by A2A TCK code generator — do not edit by hand.
2+
3+
quarkus.http.port=9999
4+
quarkus.grpc.server.use-separate-server=false
5+
6+
# Thread pool configuration for TCK testing
7+
# Limit max threads to prevent resource exhaustion in CI environments
8+
a2a.executor.core-pool-size=5
9+
a2a.executor.max-pool-size=15
10+
a2a.executor.keep-alive-seconds=60
11+
12+
# Enable debug logging for troubleshooting TCK failures
13+
quarkus.log.category."org.a2aproject.sdk.server.requesthandlers".level=DEBUG
14+
quarkus.log.category."org.a2aproject.sdk.server.events".level=DEBUG
15+
quarkus.log.category."org.a2aproject.sdk.server.tasks".level=DEBUG
16+
quarkus.log.category."org.a2aproject.sdk.server.diagnostics.ThreadStats".level=DEBUG
17+
18+
# Log to file for analysis
19+
quarkus.log.file.enable=true
20+
quarkus.log.file.path=../../reports/a2a-java-sut.log
21+
quarkus.log.file.level=DEBUG
22+
quarkus.log.console.level=INFO

0 commit comments

Comments
 (0)