diff --git a/README.md b/README.md index 63b7281..0e30b50 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,14 @@ facts, so the build fails when a claim stops being true. | Module | Post | What it shows | |---|---|---| | `embabel` | Embabel: Goal-Oriented AI Agents on the JVM | actions, goals, conditions and cost-based planning with GOAP, compared with plain Spring AI | +| `a2a` | A2A Protocol in Java: Agents That Talk to Each Other | agent card, tasks, streaming, input-required and agent-to-agent calls with the A2A Java SDK | ## Versions (verified on Maven Central, 2026-10-11) | Component | Version | Note | |---|---|---| | Embabel `embabel-agent-api` | 1.5.3 | brings Spring AI 2.0.1 and Spring Boot 4.1.1 transitively | +| A2A Java SDK `io.github.a2asdk` | 1.0.0.Alpha3 | alpha; targets A2A protocol 1.0. The newest stable release, 0.3.3.Final, targets the 0.3 protocol and its API differs | | JDK | 25 LTS | | | JUnit | 6.1.3 | | @@ -21,9 +23,9 @@ facts, so the build fails when a claim stops being true. ```bash export JAVA_HOME=/path/to/jdk-25 mvn test # everything -mvn test -pl embabel -am # one module +mvn test -pl a2a -am # one module ``` -No API key is needed. The Embabel tests use `ScriptedLlmOperations`, the scripted stand-in shipped inside +No API key is needed. The A2A agents contain no model call, because the protocol is the subject. The Embabel tests use `ScriptedLlmOperations`, the scripted stand-in shipped inside `embabel-agent-api`, and the Spring AI comparison uses a small scripted `ChatModel`. Each module writes its transcripts to `/output/` when you run the tests. diff --git a/a2a/output/01-agent-card.txt b/a2a/output/01-agent-card.txt new file mode 100644 index 0000000..960aa82 --- /dev/null +++ b/a2a/output/01-agent-card.txt @@ -0,0 +1,40 @@ +GET /.well-known/agent-card.json + +{ + "name": "Glossary Agent", + "description": "Defines Java terms", + "version": "1.0.0", + "capabilities": { + "streaming": true, + "pushNotifications": false, + "extendedAgentCard": false + }, + "defaultInputModes": [ + "text/plain" + ], + "defaultOutputModes": [ + "text/plain" + ], + "skills": [ + { + "id": "define", + "name": "Define a term", + "description": "Returns a one-sentence definition", + "tags": [ + "java", + "glossary" + ], + "examples": [ + "record" + ] + } + ], + "supportedInterfaces": [ + { + "protocolBinding": "JSONRPC", + "url": "http://127.0.0.1:PORT", + "tenant": "", + "protocolVersion": "1.0" + } + ] +} diff --git a/a2a/output/02-raw-send-message.txt b/a2a/output/02-raw-send-message.txt new file mode 100644 index 0000000..286853d --- /dev/null +++ b/a2a/output/02-raw-send-message.txt @@ -0,0 +1,61 @@ +POST / +{ + "jsonrpc": "2.0", + "id": "1", + "method": "SendMessage", + "params": { + "message": { + "messageId": "m-1", + "role": "ROLE_USER", + "parts": [ + { + "text": "record" + } + ] + }, + "configuration": { + "blocking": true + } + } +} + +Response: +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "task": { + "id": "", + "contextId": "", + "status": { + "state": "TASK_STATE_COMPLETED", + "timestamp": "