Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/deploy-site.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Roq Site Deploy

on:
push:
branches: [ main ] # Switch to the branch which should be deployed to GitHub Pages
paths:
- docs/**
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Generate Roq Site
uses: quarkiverse/quarkus-roq@v1.1
with:
github-token: ${{ secrets.GITHUB_TOKEN }} # Used to automatically get the GitHub Pages url
site-directory: ./docs/
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
permissions:
pages: write # to deploy to Pages
id-token: write # to verify the deployment originates from an appropriate source
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5
48 changes: 48 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#Maven
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
release.properties
.flattened-pom.xml

# Eclipse
.project
.classpath
.settings/
bin/

# IntelliJ
.idea
*.ipr
*.iml
*.iws

# NetBeans
nb-configuration.xml

# Visual Studio Code
.vscode
.factorypath

# OSX
.DS_Store

# Vim
*.swp
*.swo

# patch
*.orig
*.rej

# Local environment
.env

# Plugin directory
/.quarkus/cli/plugins/
# TLS Certificates
.certs/

# Web Bundler
node_modules/
66 changes: 66 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@

# A2A Java SDK Documentation

A static site built with [Roq](https://iamroq.dev), a static site generator powered by Quarkus.

## Getting Started

Install the [Roq CLI](https://iamroq.dev/docs/getting-started/) (installs [JBang](https://www.jbang.dev/download) if needed):
```bash
curl -Ls https://sh.jbang.dev | bash -s - app install --fresh --force roq@quarkiverse/quarkus-roq
```

Then:
```bash
# Start dev mode with live-reload
roq start

# Build the static site
roq generate

# Preview the generated site
roq serve
```

Dev mode runs on http://localhost:8080 (use `-p` to change the port).

## Project Structure

```
content/ Pages and collections (posts/, etc.)
templates/
layouts/ Page layouts
partials/ Reusable template fragments
data/ Structured data files (YAML/JSON)
public/ Static assets served as-is (images, etc.)
web/ JS/CSS sources (bundled by Quarkus Web Bundler)
config/
application.properties
```

## Useful Commands

```bash
roq add plugin:tagging # Add a plugin
roq add theme:default # Add a theme
roq update # Update to latest Roq version
```

## AI Coding Assistants

Give your AI assistant full context about Roq by pointing it to https://iamroq.dev/llms.txt.

For detailed skill files, run:
```bash
mvn dependency:list -DincludeGroupIds=io.quarkiverse.roq -DoutputAbsoluteArtifactFilename=true
```
Then extract skills from the `*-deployment` JARs listed in the output:
```bash
unzip -p PATH_TO_JAR META-INF/quarkus-skill.md > .claude/skills/SKILL_NAME.md
```

## Learn More

- [Roq Documentation](https://iamroq.dev/docs/)
- [Qute Template Reference](https://quarkus.io/guides/qute-reference)
- [Quarkus](https://quarkus.io/)
4 changes: 4 additions & 0 deletions docs/content/404.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
layout: 404
image: logo.svg
---
19 changes: 19 additions & 0 deletions docs/content/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: About
description: A static site generator built with Java and Quarkus. Zero config to get started, full power of the JVM when you need it.
layout: page
---

# About this site

This site is built with [Roq](https://iamroq.dev), a static site generator powered by [Quarkus](https://quarkus.io). It combines the best of tools like Jekyll and Hugo with the Java ecosystem: zero configuration to get started, blazing fast live-reload in dev mode, and full access to Java when you need it.

## Authors

<div class="authors">
{#for id in cdi:authors.fields}
{#let author=cdi:authors.get(id)}
{#roq/authorCard name=author.name avatar=author.avatar?? nickname=author.nickname profile=author.profile /}
Comment thread
ehsavoie marked this conversation as resolved.
{/for}
</div>

8 changes: 8 additions & 0 deletions docs/content/announces.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: Announcements
description: Release announcements and news from the A2A Java SDK project.
layout: blog
paginate:
collection: posts
size: 10
---
210 changes: 210 additions & 0 deletions docs/content/client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
---
title: A2A Client Guide
description: Communicate with A2A-compliant agents using the A2A Java SDK client.
layout: page
---

# A2A Client

The A2A Java SDK provides a Java client for communicating with any A2A-compliant agent. Supports JSON-RPC 2.0, gRPC, and HTTP+JSON/REST transports.

## 1. Add the Client Dependency

```xml
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-client</artifactId>
<!-- Use a released version from https://github.com/a2aproject/a2a-java/releases -->
<version>$\{org.a2aproject.sdk.version}</version>
</dependency>
```

The client artifact includes the JSON-RPC transport by default. For gRPC or REST, add the corresponding transport:

```xml
<!-- gRPC transport -->
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-client-transport-grpc</artifactId>
<version>$\{org.a2aproject.sdk.version}</version>
</dependency>

<!-- HTTP+JSON/REST transport -->
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-client-transport-rest</artifactId>
<version>$\{org.a2aproject.sdk.version}</version>
</dependency>
```

## 2. Create a Client

```java
// Resolve the agent card from the server
AgentCard agentCard = A2ACardResolver.builder()
.baseUrl("http://localhost:1234")
.build()
.getAgentCard();

// Configure accepted output modes
ClientConfig clientConfig = new ClientConfig.Builder()
.setAcceptedOutputModes(List.of("text"))
.build();

// Define event consumers
List<BiConsumer<ClientEvent, AgentCard>> consumers = List.of(
(event, card) -> {
if (event instanceof MessageEvent messageEvent) {
// handle message
} else if (event instanceof TaskEvent taskEvent) {
// handle task
} else if (event instanceof TaskUpdateEvent updateEvent) {
// handle task update
}
}
);

// Build the client
Client client = Client
.builder(agentCard)
.clientConfig(clientConfig)
.withTransport(JSONRPCTransport.class, new JSONRPCTransportConfig())
.addConsumers(consumers)
.streamingErrorHandler(error -> { /* handle errors */ })
.build();
```

## 3. Send Messages

```java
// Send a text message (streaming used automatically if supported)
Message message = A2A.toUserMessage("tell me a joke");
client.sendMessage(message);

// Send with per-call custom consumers
client.sendMessage(message, customConsumers, customErrorHandler);

// Send with a call context
client.sendMessage(message, clientCallContext);
```

## Task Management

```java
// Get task state
Task task = client.getTask(new TaskQueryParams("task-1234"));
Task task = client.getTask(new TaskQueryParams("task-1234", 10)); // with history limit

// Cancel a task
Task cancelled = client.cancelTask(new TaskIdParams("task-1234"));

// Subscribe to an ongoing task
client.subscribeToTask(new TaskIdParams("task-1234"));
client.subscribeToTask(taskIdParams, customConsumers, customErrorHandler);

// Retrieve the server agent card
AgentCard serverCard = client.getAgentCard();
```

## Push Notifications

```java
// Set a push notification configuration
PushNotificationConfig pushConfig = PushNotificationConfig.builder()
.url("https://example.com/callback")
.authenticationInfo(new AuthenticationInfo(List.of("jwt"), null))
.build();

TaskPushNotificationConfig taskConfig = TaskPushNotificationConfig.builder()
.taskId("task-1234")
.pushNotificationConfig(pushConfig)
.build();

client.createTaskPushNotificationConfiguration(taskConfig);

// List configurations
List<TaskPushNotificationConfig> configs =
client.listTaskPushNotificationConfigurations(
new ListTaskPushNotificationConfigParams("task-1234"));

// Delete a configuration
client.deleteTaskPushNotificationConfigurations(
new DeleteTaskPushNotificationConfigParams("task-1234", "config-4567"));
```

## Transport Configuration

### JSON-RPC with a Custom HTTP Client

```java
// Use a custom JDK HTTP client
HttpClient jdkHttpClient = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(5))
.followRedirects(HttpClient.Redirect.NORMAL)
.build();

Client client = Client
.builder(agentCard)
.withTransport(JSONRPCTransport.class,
new JSONRPCTransportConfig(new JdkA2AHttpClient(jdkHttpClient)))
.build();
```

### gRPC

```java
Function<String, Channel> channelFactory = agentUrl ->
ManagedChannelBuilder.forTarget(agentUrl).build();

Client client = Client
.builder(agentCard)
.withTransport(GrpcTransport.class, new GrpcTransportConfig(channelFactory))
.build();
```

### Multiple Transports

```java
Client client = Client
.builder(agentCard)
.withTransport(GrpcTransport.class, new GrpcTransportConfig(channelFactory))
.withTransport(JSONRPCTransport.class, new JSONRPCTransportConfig())
.withTransport(RestTransport.class, new RestTransportConfig())
.build();
```

## Communicating with v0.3 Agents

Use `Client_v0_3` to communicate with agents that only support protocol v0.3:

```xml
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-client</artifactId>
<version>$\{org.a2aproject.sdk.version}</version>
</dependency>
<dependency>
<groupId>org.a2aproject.sdk</groupId>
<artifactId>a2a-java-sdk-compat-0.3-client-transport-jsonrpc</artifactId>
<version>$\{org.a2aproject.sdk.version}</version>
</dependency>
```

```java
AgentCard card = A2ACardResolver.builder().baseUrl("http://localhost:1234")
.build().getAgentCard();

AgentInterface v03Interface = card.supportedInterfaces().stream()
.filter(i -> A2AProtocol_v0_3.PROTOCOL_VERSION.equals(i.protocolVersion()))
.findFirst().orElseThrow();

Client_v0_3 client = ClientBuilder_v0_3.forUrl(v03Interface.url())
.withTransport(JSONRPCTransport_v0_3.class, new JSONRPCTransportConfigBuilder_v0_3())
.build();
```

## Examples

- [Hello World Client](https://github.com/a2aproject/a2a-java/blob/main/examples/helloworld/client/README.md) — Java client talking to a Python A2A server
- [Hello World Server](https://github.com/a2aproject/a2a-java/blob/main/examples/helloworld/server/README.md) — Python client talking to a Java A2A server
- [a2a-samples repository](https://github.com/a2aproject/a2a-samples/tree/main/samples/java/agents) — More agent examples
Loading