Skip to content

Commit e34b12c

Browse files
authored
Merge pull request #44 from kabir/align-a2ajava
Align with latest a2a-java changes
2 parents 01cc1e8 + 118361a commit e34b12c

18 files changed

Lines changed: 260 additions & 156 deletions

File tree

.github/workflows/run-tck.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77

88
env:
99
# Tag of the TCK
10-
TCK_VERSION: spec_1.0 # 1.0 WIP branch
10+
TCK_VERSION: main # 1.0 WIP branch
1111
# Tells uv to not need a venv, and instead use system
1212
UV_SYSTEM_PYTHON: 1
1313

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
This is the integration of the [A2A Java SDK](https://github.com/a2aproject/a2a-java) for use in Jakarta servers. It is currently tested on **WildFly**, but it should be usable in other compliant Jakarta servers such as Tomcat, Jetty, and OpenLiberty. For Quarkus, use the reference implementation in the [A2A Java SDK](https://github.com/a2aproject/a2a-java) project.
44

5-
This implementation is aligned with **A2A Protocol Specification 1.0.0**.
5+
This implementation is aligned with **A2A Protocol Specification 1.0** and uses **A2A Java SDK 1.0.0.Alpha2** (pre-release).
66

77
For more information about the A2A protocol, see [here](https://github.com/a2aproject/A2A).
88

examples/simple/README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,19 @@ Currently, the `grpc` dependencies also include the `jsonrpc` ones, mainly becau
1515

1616
Note that we need to exclude some transitive dependencies of jars which are provided by WildFly. Other Jakarta runtimes may provide different dependencies and need different exclusions.
1717

18-
To create your own agent, you need to implement `AgentCard` and `AgentExecutor` beans.
18+
To create your own agent, you need to implement `AgentCard` and `AgentExecutor` beans.
1919

20-
* The `AgentCard` shows the capabilities of the agent.
21-
* The `AgentExecutor` handles the interaction with the LLM.
20+
* The `AgentCard` shows the capabilities of the agent, including supported transports and protocol version. This is the public version of the AgentCard, as this example does not provide an extended AgentCard. To provide an extended AgentCard, you produce it the same way, but with the @ExtendedAgentCard qualifier.
21+
* The `AgentExecutor` handles the interaction with the LLM and task execution.
2222

2323
You can see our simple implementations at:
2424

25-
* [`SimpleExampleAgentCardProducer.java`](./server/src/main/java/org/wildfly/extras/a2a/examples/simple/SimpleExampleAgentCardProducer.java) - note that this has some logic to determine the transports that exist on the classpath, which is then added to the additionalInterfaces of the AgentCard
26-
* [`SimpleExampleAgentExecutorProducer.java`](./server/src/main/java/org/wildfly/extras/a2a/examples/simple/SimpleExampleAgentExecutorProducer.java)
25+
* [`SimpleExampleAgentCardProducer.java`](./server/src/main/java/org/wildfly/extras/a2a/examples/simple/SimpleExampleAgentCardProducer.java) - configures the agent card with transport URLs and protocol version. Note that this has logic to determine which transports exist on the classpath, which are then added to the supportedInterfaces of the AgentCard.
26+
* [`SimpleExampleAgentExecutorProducer.java`](./server/src/main/java/org/wildfly/extras/a2a/examples/simple/SimpleExampleAgentExecutorProducer.java) - implements task execution using `AgentEmitter` to manage task lifecycle and artifacts
27+
28+
The `AgentExecutor` interface provides two methods:
29+
* `execute(RequestContext context, AgentEmitter emitter)` - handles incoming requests, using the `AgentEmitter` to signal work progress, add artifacts, and complete tasks
30+
* `cancel(RequestContext context, AgentEmitter emitter)` - handles cancellation requests for running tasks
2731

2832
In this example, the LLM interaction is mocked. For more advanced examples on how to interact with an LLM, please refer to the a2a-samples repository.
2933

examples/simple/server/src/main/java/org/wildfly/extras/a2a/examples/simple/SimpleExampleAgentExecutorProducer.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88

99
import io.a2a.server.agentexecution.AgentExecutor;
1010
import io.a2a.server.agentexecution.RequestContext;
11-
import io.a2a.server.events.EventQueue;
12-
import io.a2a.server.tasks.TaskUpdater;
11+
import io.a2a.server.tasks.AgentEmitter;
1312
import io.a2a.spec.A2AError;
1413
import io.a2a.spec.Part;
1514
import io.a2a.spec.TaskNotCancelableError;
@@ -25,11 +24,10 @@ public AgentExecutor mockExecutor() {
2524

2625
private static class SimpleExampleAgentExecutor implements AgentExecutor {
2726
@Override
28-
public void execute(RequestContext context, EventQueue eventQueue) throws A2AError {
29-
TaskUpdater updater = new TaskUpdater(context, eventQueue);
27+
public void execute(RequestContext context, AgentEmitter emitter) throws A2AError {
3028

3129
// Signal we've started working
32-
updater.startWork();
30+
emitter.startWork();
3331

3432
// Get the name sent in the user's message
3533
List<Part<?>> partsList = context.getMessage().parts();
@@ -42,14 +40,14 @@ public void execute(RequestContext context, EventQueue eventQueue) throws A2AErr
4240
// Simulate doing work with the LLM, and adding that as an artifact.
4341
// In this case we just add "Hello <name>" to the list of aritfacts
4442
String response = "Hello " + name;
45-
updater.addArtifact(Collections.singletonList(new TextPart(response)), null, "response", null);
43+
emitter.addArtifact(Collections.singletonList(new TextPart(response)), null, "response", null);
4644

4745
// We have completed our simple example Task
48-
updater.complete();
46+
emitter.complete();
4947
}
5048

5149
@Override
52-
public void cancel(RequestContext context, EventQueue eventQueue) throws A2AError {
50+
public void cancel(RequestContext context, AgentEmitter emitter) throws A2AError {
5351
throw new TaskNotCancelableError();
5452
}
5553
}

impl/grpc/src/main/java/org/wildfly/extras/a2a/server/apps/grpc/GrpcBeanInitializer.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import jakarta.enterprise.inject.Instance;
1010
import jakarta.inject.Inject;
1111

12+
import io.a2a.server.ExtendedAgentCard;
1213
import io.a2a.server.PublicAgentCard;
1314
import io.a2a.server.requesthandlers.RequestHandler;
1415
import io.a2a.server.util.async.Internal;
@@ -29,6 +30,10 @@ public class GrpcBeanInitializer {
2930
@PublicAgentCard
3031
AgentCard agentCard;
3132

33+
@Inject
34+
@ExtendedAgentCard
35+
Instance<AgentCard> extendedAgentCard;
36+
3237
@Inject
3338
RequestHandler requestHandler;
3439

@@ -46,14 +51,15 @@ public void onStartup(@Observes @Initialized(ApplicationScoped.class) Object ini
4651
try {
4752
// Cache CDI beans for gRPC threads to use since CDI is not available on those threads
4853
CallContextFactory ccf = callContextFactory.isUnsatisfied() ? null : callContextFactory.get();
49-
WildFlyGrpcHandler.setStaticBeans(agentCard, requestHandler, ccf, executor);
54+
AgentCard extCard = extendedAgentCard.isUnsatisfied() ? null : extendedAgentCard.get();
55+
WildFlyGrpcHandler.setStaticBeans(agentCard, extCard, requestHandler, ccf, executor);
5056
} catch (Exception e) {
5157
e.printStackTrace();
5258
}
5359
}
5460

5561
@PreDestroy
5662
public void cleanup() {
57-
WildFlyGrpcHandler.setStaticBeans(null, null, null, null);
63+
WildFlyGrpcHandler.setStaticBeans(null, null, null, null, null);
5864
}
5965
}

impl/grpc/src/main/java/org/wildfly/extras/a2a/server/apps/grpc/WildFlyGrpcHandler.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class WildFlyGrpcHandler extends GrpcHandler {
2323

2424
// Static cache populated during application startup by GrpcBeanInitializer
2525
private static volatile AgentCard staticAgentCard;
26+
private static volatile AgentCard staticExtendedAgentCard;
2627
private static volatile RequestHandler staticRequestHandler;
2728
private static volatile CallContextFactory staticCallContextFactory;
2829
private static volatile Executor staticExecutor;
@@ -35,8 +36,9 @@ public WildFlyGrpcHandler() {
3536
* Called by GrpcBeanInitializer during CDI initialization to cache beans
3637
* for use by gRPC threads where CDI is not available.
3738
*/
38-
static void setStaticBeans(AgentCard agentCard, RequestHandler requestHandler, CallContextFactory callContextFactory, Executor executor) {
39+
static void setStaticBeans(AgentCard agentCard, AgentCard extendedAgentCard, RequestHandler requestHandler, CallContextFactory callContextFactory, Executor executor) {
3940
staticAgentCard = agentCard;
41+
staticExtendedAgentCard = extendedAgentCard;
4042
staticRequestHandler = requestHandler;
4143
staticCallContextFactory = callContextFactory;
4244
staticExecutor = executor;
@@ -58,6 +60,11 @@ protected AgentCard getAgentCard() {
5860
return staticAgentCard;
5961
}
6062

63+
@Override
64+
protected AgentCard getExtendedAgentCard() {
65+
return staticExtendedAgentCard; // Can be null if not configured
66+
}
67+
6168
@Override
6269
protected CallContextFactory getCallContextFactory() {
6370
return staticCallContextFactory; // Can be null if not configured

0 commit comments

Comments
 (0)