Skip to content

Commit caf22fe

Browse files
feat: java a2a sdk (#1)
Signed-off-by: Dominik Kolonits <dkolonit@cisco.com> Signed-off-by: Janos Sarusi-Kis <janossk@cisco.com> Co-authored-by: Janos Sarusi-Kis <janossk@cisco.com>
1 parent fbf1ee2 commit caf22fe

21 files changed

Lines changed: 2182 additions & 0 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright AGNTCY Contributors (https://github.com/agntcy)
2+
# SPDX-License-Identifier: Apache-2.0
3+
---
4+
5+
name: Setup Java Environment
6+
description: Setup environment to build/test Java applications with Maven
7+
inputs:
8+
java-version:
9+
description: "Java version to install"
10+
required: false
11+
default: "21"
12+
distribution:
13+
description: "Java distribution to use"
14+
required: false
15+
default: "temurin"
16+
outputs:
17+
cache-hit:
18+
description: "Whether we hit the cache"
19+
value: ${{ steps.setup-java.outputs.cache-hit }}
20+
runs:
21+
using: "composite"
22+
steps:
23+
- name: Setup Java (with Maven cache)
24+
id: setup-java
25+
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
26+
with:
27+
distribution: ${{ inputs.distribution }}
28+
java-version: ${{ inputs.java-version }}
29+
cache: maven
30+
cache-dependency-path: "**/pom.xml"
31+
32+
- name: Setup Taskfile
33+
uses: ./.github/actions/setup-task
34+
35+
- name: Update GITHUB_PATH
36+
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
37+
shell: bash
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Copyright AGNTCY Contributors (https://github.com/agntcy)
2+
# SPDX-License-Identifier: Apache-2.0
3+
---
4+
name: Setup Rust Environment
5+
description: Setup Rust toolchain for building protoc plugins
6+
inputs:
7+
toolchain:
8+
description: "Rust toolchain to use"
9+
required: false
10+
default: "stable"
11+
cache-enabled:
12+
description: "Enable rust cache"
13+
required: false
14+
default: "true"
15+
cache-directories:
16+
description: "Additional cache directories (whitespace-separated)"
17+
required: false
18+
default: |
19+
~/.cargo/bin
20+
~/.cargo/.crates.toml
21+
~/.cargo/.crates2.json
22+
runs:
23+
using: "composite"
24+
steps:
25+
- name: Setup Rust
26+
id: setup-rust
27+
uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
28+
with:
29+
rustflags: ""
30+
cache: ${{ inputs.cache-enabled }}
31+
cache-on-failure: false
32+
cache-shared-key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }}
33+
cache-all-crates: true
34+
cache-bin: false
35+
cache-directories: ${{ inputs.cache-directories }}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Copyright AGNTCY Contributors (https://github.com/agntcy)
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
---
5+
6+
name: Setup Task with Cache
7+
description: Setup Task (go-task/task) with GitHub Actions caching to prevent rate limiting
8+
inputs:
9+
version:
10+
description: 'Task version to install (e.g., "3.39.2", "latest")'
11+
required: false
12+
default: 'latest'
13+
cache-enabled:
14+
description: 'Enable caching of the Task binary'
15+
required: false
16+
default: 'true'
17+
github-token:
18+
description: 'GitHub token for API requests'
19+
required: false
20+
default: ${{ github.token }}
21+
22+
outputs:
23+
cache-hit:
24+
description: 'Whether the Task binary was retrieved from cache'
25+
value: ${{ steps.cache.outputs.cache-hit }}
26+
version:
27+
description: 'The actual version of Task that was installed'
28+
value: ${{ steps.get-version.outputs.version }}
29+
30+
runs:
31+
using: "composite"
32+
steps:
33+
- name: Determine Task version
34+
id: get-version
35+
shell: bash
36+
run: |
37+
if [ "${{ inputs.version }}" == "latest" ]; then
38+
VERSION=$(curl -s -H "Authorization: Bearer ${{ inputs.github-token }}" -H "Accept: application/vnd.github+json" https://api.github.com/repos/go-task/task/releases/latest | grep '"tag_name"' | cut -d'"' -f4)
39+
if [[ -z "$VERSION" ]]; then
40+
VERSION="v3.39.2"
41+
fi
42+
else
43+
VERSION="${{ inputs.version }}"
44+
if [[ ! "$VERSION" =~ ^v ]]; then
45+
VERSION="v$VERSION"
46+
fi
47+
fi
48+
echo "version=$VERSION" >> $GITHUB_OUTPUT
49+
50+
- name: Determine platform
51+
id: platform
52+
shell: bash
53+
run: |
54+
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
55+
ARCH=$(uname -m)
56+
case $ARCH in
57+
x86_64) ARCH="amd64" ;;
58+
aarch64|arm64) ARCH="arm64" ;;
59+
armv7l) ARCH="arm" ;;
60+
esac
61+
case $OS in
62+
darwin) OS="darwin" ;;
63+
linux) OS="linux" ;;
64+
mingw*|msys*|cygwin*) OS="windows" ;;
65+
esac
66+
[[ $OS == "windows" ]] && BINARY_NAME="task.exe" || BINARY_NAME="task"
67+
echo "os=$OS" >> $GITHUB_OUTPUT
68+
echo "arch=$ARCH" >> $GITHUB_OUTPUT
69+
echo "binary_name=$BINARY_NAME" >> $GITHUB_OUTPUT
70+
71+
- name: Setup GitHub PATH
72+
shell: bash
73+
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
74+
75+
- name: Setup cache for Task binary
76+
id: cache
77+
if: inputs.cache-enabled == 'true'
78+
uses: actions/cache@v4
79+
with:
80+
path: ~/.local/bin/${{ steps.platform.outputs.binary_name }}
81+
key: task-${{ steps.get-version.outputs.version }}-${{ steps.platform.outputs.os }}-${{ steps.platform.outputs.arch }}
82+
83+
- name: Download and install Task
84+
if: steps.cache.outputs.cache-hit != 'true'
85+
shell: bash
86+
run: |
87+
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -b ~/.local/bin -d ${{ steps.get-version.outputs.version }}
88+
89+
- name: Verify installation
90+
shell: bash
91+
run: task --version

.github/workflows/ci.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright AGNTCY Contributors (https://github.com/agntcy)
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
name: CI
5+
6+
on:
7+
push:
8+
branches: [ main ]
9+
pull_request:
10+
branches: [ main ]
11+
12+
concurrency:
13+
group: ${{ github.workflow }}-${{ github.ref }}
14+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
15+
16+
jobs:
17+
build:
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@v4
21+
22+
- name: Setup Rust
23+
uses: ./.github/actions/setup-rust
24+
with:
25+
cache-enabled: false
26+
27+
- name: Setup Java
28+
uses: ./.github/actions/setup-java
29+
30+
- name: Install protoc-gen-slimrpc-java
31+
run: cargo install agntcy-protoc-slimrpc-plugin --version 1.3.0 --locked
32+
33+
- uses: bufbuild/buf-setup-action@v1
34+
with:
35+
github_token: ${{ github.token }}
36+
37+
- name: Generate SlimRPC stubs
38+
run: task generate
39+
40+
- name: Build
41+
run: task build
42+
43+
- name: Test
44+
run: task test

.gitignore

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Maven
2+
target/
3+
*.jar
4+
*.war
5+
*.ear
6+
*.class
7+
dependency-reduced-pom.xml
8+
9+
# IDE
10+
.idea/
11+
*.iml
12+
.vscode/
13+
.settings/
14+
.classpath
15+
.project
16+
.factorypath
17+
18+
# OS
19+
.DS_Store
20+
Thumbs.db
21+
22+
# Logs
23+
*.log

README.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# SLIM A2A Java
2+
3+
A2A (Agent-to-Agent) protocol over [SLIM](https://github.com/agntcy/slim) transport for Java.
4+
5+
This library provides an adapter between the [A2A Java SDK](https://github.com/a2aproject/a2a-java) and SLIM's RPC transport, allowing A2A agents to communicate over the SLIM network.
6+
7+
## Project Structure
8+
9+
```
10+
slim-a2a-java/
11+
buf.yaml / buf.gen.yaml # Protobuf / SlimRPC code generation config
12+
Taskfile.yaml # Task runner commands
13+
slim-a2a/ # Library module
14+
generated/slimrpc/ # Generated SlimRPC stubs (A2AServiceSlimrpc.java)
15+
src/main/java/ # Adapter classes
16+
io/agntcy/slim/a2a/
17+
SlimA2AHandler.java # Server-side: RequestHandler -> A2AServiceServer
18+
SlimA2AClient.java # Client-side: domain types over SlimRPC
19+
SlimHelper.java # SLIM bootstrap helpers
20+
A2ARpcErrorMapping.java # A2A error <-> RPC error mapping
21+
examples/echo-agent/ # Echo agent example
22+
src/main/java/
23+
io/agntcy/slim/a2a/examples/echo/
24+
EchoAgentExecutor.java # Simple echo AgentExecutor
25+
ServerMain.java # Server entry point
26+
ClientMain.java # Client entry point
27+
```
28+
29+
## Prerequisites
30+
31+
- Java 21+
32+
- Maven 3.9+
33+
- A running SLIM gateway (e.g. `slimctl up`)
34+
- [Buf CLI](https://buf.build/docs/installation) (for regenerating stubs)
35+
- `protoc-gen-slimrpc-java` on PATH (for regenerating stubs)
36+
37+
## Dependencies
38+
39+
The library depends on:
40+
41+
- `io.agntcy.slim:slim-bindings-java` -- SLIM Java bindings (JNA-based)
42+
- `org.a2aproject.sdk:a2a-java-sdk-server-common` -- A2A SDK server core
43+
- `org.a2aproject.sdk:a2a-java-sdk-spec-grpc` -- A2A protobuf types and ProtoUtils mappers
44+
45+
These must be available in your local Maven repository. If they are not published to a remote repository, install them locally first:
46+
47+
```bash
48+
# Install SLIM Java bindings
49+
cd /path/to/slim/data-plane/bindings/java
50+
mvn install -DskipTests
51+
52+
# Install A2A Java SDK
53+
cd /path/to/a2a-java
54+
mvn install -DskipTests
55+
```
56+
57+
## Building
58+
59+
```bash
60+
task build
61+
```
62+
63+
## Regenerating SlimRPC Stubs
64+
65+
The generated stubs are checked in under `slim-a2a/generated/slimrpc/`. To regenerate:
66+
67+
```bash
68+
task generate
69+
```
70+
71+
This requires `protoc-gen-slimrpc-java` on your PATH. Build it from the SLIM repository:
72+
73+
```bash
74+
cd /path/to/slim/data-plane
75+
cargo build --release -p agntcy-protoc-slimrpc-plugin
76+
# Binary: target/release/protoc-gen-slimrpc-java
77+
```
78+
79+
## Running the Echo Agent Example
80+
81+
### 1. Start a SLIM gateway
82+
83+
```bash
84+
slimctl slim start --endpoint 127.0.0.1:46357
85+
```
86+
87+
### 2. Start the server
88+
89+
In a second terminal:
90+
91+
```bash
92+
task echo-server
93+
```
94+
95+
Wait for `SLIM_A2A_SERVER_READY` to appear.
96+
97+
### 3. Run the client
98+
99+
In a third terminal:
100+
101+
```bash
102+
task echo-client
103+
```
104+
105+
## Architecture
106+
107+
The library follows the same adapter pattern as
108+
[slim-a2a-go](https://github.com/agntcy/slim-a2a-go),
109+
[slim-a2a-python](https://github.com/agntcy/slim-a2a-python), and
110+
[slim-a2a-dotnet](https://github.com/agntcy/slim-a2a-dotnet):
111+
112+
```
113+
SLIM Transport
114+
115+
┌────────────┼────────────┐
116+
│ slim-a2a-java Library │
117+
│ │ │
118+
│ ┌─────────┴──────────┐ │
119+
│ │ Generated SlimRPC │ │ (A2AServiceSlimrpc.java)
120+
│ │ stubs (buf gen) │ │
121+
│ └─────────┬──────────┘ │
122+
│ │ │
123+
│ ┌─────────┴──────────┐ │
124+
│ │ SlimA2AHandler │ │ Server: adapts RequestHandler -> A2AServiceServer
125+
│ │ SlimA2AClient │ │ Client: wraps A2AServiceClient with domain types
126+
│ │ A2ARpcErrorMapping │ │ Error translation
127+
│ │ SlimHelper │ │ SLIM lifecycle bootstrap
128+
│ └─────────┬──────────┘ │
129+
└────────────┼────────────┘
130+
131+
┌────────────┼────────────┐
132+
│ a2a-java SDK │
133+
│ RequestHandler │
134+
│ AgentExecutor │
135+
│ ProtoUtils (mappers) │
136+
│ TaskStore / QueueMgr │
137+
└─────────────────────────┘
138+
```
139+
140+
Proto types from `a2a-java-sdk-spec-grpc` are reused on the classpath (split-package approach); no custom proto type generation or converter is needed.
141+
142+
## License
143+
144+
Apache-2.0. See [LICENSE](LICENSE).

0 commit comments

Comments
 (0)