Skip to content
Draft
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
3 changes: 3 additions & 0 deletions packages/a2a_dart/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://dart.dev/guides/libraries/private-files
# Created by `dart pub`
.dart_tool/
5 changes: 5 additions & 0 deletions packages/a2a_dart/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# a2a_dart Change Log

## 0.1.0

- Initial version of the Dart A2A library.
200 changes: 200 additions & 0 deletions packages/a2a_dart/DESIGN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
# A2A Dart Library Design Document

## 1. Overview

This document outlines the design for a pure Dart implementation of the Agent2Agent (A2A) protocol. The `a2a_dart` library provides both client and server components for A2A communication. The client is platform-independent and can be used in web applications, while the server is designed for native platforms that support `dart:io`.

The primary goal is to create a library that is:

- **Comprehensive**: Implements the full A2A specification.
- **Idiomatic**: Feels natural to Dart and Flutter developers.
- **Type-Safe**: Leverages Dart's strong type system to prevent errors.
- **Extensible**: Allows for future expansion and customization.

## 2. Goals and Non-Goals

### Goals

- Provide a type-safe, idiomatic Dart implementation of the A2A protocol.
- Support the full A2A specification, including all data models and RPC methods.
- Offer a clear and easy-to-use client API for interacting with A2A agents.
- Provide a flexible and extensible server framework for building A2A agents in Dart.
- Adhere to Dart and Flutter best practices, including null safety, effective asynchronous programming, and clean architecture.

### Non-Goals

- **Transports**: Implement transport protocols other than JSON-RPC and SSE over HTTP. gRPC and REST transports are out of scope for the initial version.
- **Push Notifications**: The server-side push notification mechanism will not be implemented initially. The client will support sending the configuration, but the server will not act on it.
- **Agent Framework**: Provide a full-fledged agent framework with built-in AI capabilities. This library focuses on the communication protocol.
- **Extensions**: Implement any of the optional extensions to the A2A protocol in the initial version.

## 3. Implemented A2A Features

The `a2a_dart` library implements the following features from the A2A specification:

### Core Concepts

- **Client & Server**: Foundational components for initiating and responding to A2A requests.
- **Agent Card**: Full implementation for agent discovery and capability advertisement.
- **Task**: State management for all agent operations.
- **Message**: The primary object for communication turns.
- **Part**: Support for `TextPart`, `FilePart`, and `DataPart` to enable rich content exchange.
- **Artifact**: Handling for agent-generated outputs.
- **Context**: Grouping related tasks.

### Transport Protocols

- **JSON-RPC 2.0**: The primary transport protocol for all RPC methods over HTTP/S.
- **Server-Sent Events (SSE)**: For real-time, streaming updates from the server to the client (`message/stream` and `tasks/resubscribe`).

### Data Models

- A complete, type-safe implementation of all data objects defined in the specification, including:
- `Task`, `TaskStatus`, `TaskState`
- `Message`, `Part` (and its variants)
- `AgentCard` (and all nested objects like `AgentSkill`, `AgentProvider`, etc.)
- `Artifact`
- `PushNotificationConfig` (client-side only)
- All JSON-RPC request, response, and error structures.

### RPC Methods

- The library provides client methods and server-side handlers for the following A2A RPC methods:
- `get_agent_card` (via HTTP GET)
- `create_task`
- `message/stream`
- `execute_task`

### Authentication

- The library will be designed to work with standard HTTP authentication mechanisms (e.g., Bearer Token, API Key) by providing hooks (middleware) for adding authentication headers to client requests.

## 4. Architecture

The `a2a_dart` library is structured with a single public entry point, `lib/a2a_dart.dart`, which exports the core, client, and server APIs. The internal structure is organized as follows:

- **`lib/src`**: Contains the private implementation of the library.
- **`core`**: Contains the platform-independent data models and types defined in the A2A specification.
- **`client`**: Provides the `A2AClient` class and transport implementations (`HttpTransport`, `SseTransport`).
- **`server`**: Offers a framework for building A2A agents. It uses a conditional export (`a2a_server.dart`) to provide a native implementation (`io/a2a_server.dart`) and a web stub (`web/a2a_server.dart`).

```mermaid
graph TD
subgraph Public API
A[lib/a2a_dart.dart]
end

subgraph "Implementation (lib/src)"
B[Core]
C[Client]
D[Server]
end

A --> B
A --> C
A --> D

B --> B1[Data Models]

C --> C1[A2AClient]
C --> C2[Transport]
C2 --> C2a[HttpTransport]
C2 --> C2b[SseTransport]

D --> D1[a2a_server.dart (conditional export)]
D1 --> D1a[io/a2a_server.dart]
D1 --> D1b[web/a2a_server.dart]
D --> D2[RequestHandler]
```

## 4. Data Models

All data models from the A2A specification will be implemented as immutable Dart classes. To reduce boilerplate and ensure correctness, we will use the `json_serializable` and `freezed` packages for JSON serialization and value equality.

- **Immutability**: All model classes will be immutable.
- **JSON Serialization**: Each class will have `fromJson` and `toJson` methods.
- **Null Safety**: All fields will be null-safe.

Example `AgentCard` model:

```dart
import 'package:freezed_annotation/freezed_annotation.dart';

part 'agent_card.freezed.dart';
part 'agent_card.g.dart';

@freezed
class AgentCard with _$AgentCard {
const factory AgentCard({
required String protocolVersion,
required String name,
required String description,
required String url,
// ... other fields
}) = _AgentCard;

factory AgentCard.fromJson(Map<String, dynamic> json) => _$AgentCardFromJson(json);
}
```

## 5. Client API

The client API will be centered around the `A2AClient` class. This class will provide methods for each of the A2A RPC calls, such as `sendMessage`, `getTask`, and `cancelTask`.

- **Asynchronous**: All API methods will be asynchronous, returning `Future`s.
- **Transport Agnostic**: The `A2AClient` delegates the actual HTTP communication to a `Transport` interface. This allows for different transport implementations, with `HttpTransport` providing basic request-response and `SseTransport` extending it for streaming.

Example `A2AClient` usage:

```dart
final log = Logger('MyClient');
final client = A2AClient(
url: 'https://example.com/a2a',
transport: SseTransport(url: 'https://example.com/a2a', log: log),
);

// Create a task
final task = await client.createTask(Message(
messageId: '1',
role: Role.user,
parts: [Part.text(text: 'Hello, agent!')],
));

// Execute the task and get a stream of events
final stream = client.executeTask(task.id);
await for (final event in stream) {
// process events
}
```

## 6. Server Framework

The server framework will provide the building blocks for creating A2A-compliant agents in Dart.

- **`A2AServer`**: A top-level class that listens for incoming HTTP requests. It is conditionally exported to support both native and web platforms. On native, it uses `dart:io` to create an HTTP server. On the web, it throws an `UnsupportedError` if instantiated.
- **`RequestHandler`**: An interface for handling specific A2A methods. Developers will implement this interface to define their agent's behavior. The `handle` method returns a `HandlerResult` which can be a `SingleResult` for a single response or a `StreamResult` for a streaming response.
- **`TaskManager`**: A class responsible for managing the lifecycle of tasks.

## 7. Error Handling

Errors will be handled using a combination of exceptions and a `Result` type. Network and transport-level errors will throw exceptions, while A2A-specific errors will be returned as part of a `Result` object, allowing for more granular error handling.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The design document states that A2A-specific errors will be returned as part of a Result type. However, the client implementation in a2a_client.dart throws an A2AException for JSON-RPC errors. This is a deviation from the documented design. While using exceptions is a valid error handling strategy, the implementation should be consistent with the design document. Please either update the implementation to use a Result type or update the design document to reflect the use of exceptions for A2A-specific errors.


## 8. Dependencies

- `http`: For making HTTP requests.
- `freezed`: For immutable data classes.
- `json_serializable`: For JSON serialization.
- `shelf`: For building the server.
- `shelf_router`: For routing requests on the server.
- `uuid`: For generating unique IDs.

## 9. Testing

The library will have a comprehensive suite of unit and integration tests.

- **Unit Tests**: Will cover individual classes and methods in isolation.
- **Integration Tests**: Will test the client and server components together, as well as against a known-good A2A implementation.

## 10. Documentation

All public APIs will be thoroughly documented with DartDoc comments. The package will also include a comprehensive `README.md` and example usage.
59 changes: 59 additions & 0 deletions packages/a2a_dart/GEMINI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# A2A Dart Package

## Overview

This package provides a Dart implementation of the A2A (Agent-to-Agent) protocol. It includes a client for interacting with A2A servers and a server framework for building A2A agents.

Here's the overview of the layout of this pacakge:

```
├── analysis_options.yaml
├── lib
│ ├── a2a_dart.dart
│ └── src
│ ├── client
│ │ ├── a2a_client.dart
│ │ ├── transport.dart
│ │ ├── http_transport.dart
│ │ └── sse_transport.dart
│ ├── core
│ │ ├── agent_card.dart
│ │ ├── message.dart
│ │ ├── task.dart
│ │ └── ... (other data models)
│ └── server
│ ├── a2a_server.dart (conditional export)
│ ├── request_handler.dart
│ ├── io
│ │ └── a2a_server.dart (native implementation)
│ └── web
│ └── a2a_server.dart (web stub)
├── pubspec.yaml
└── test
├── client
│ └── a2a_client_test.dart
├── integration
│ └── client_server_test.dart
└── server
└── a2a_server_test.dart
```

## Documentation and References

The design document in the `DESIGN.md` file provides an overview of the package's architecture and design decisions.

The high level overview of the package in the `README.md` file.

The A2A protocol specification is defined here: [A2A Protocol](https://a2a-protocol.org/latest/specification/).

## Client

`A2AClient` interacts with A2A servers. It supports RPC calls like `get_agent_card`, `create_task`, and `execute_task`. Communication is handled by a `Transport` interface, with `HttpTransport` for single requests and `SseTransport` for streaming.

## Server

`A2AServer` is a framework for building A2A agents on top of the `shelf` package. It uses a pipeline of `RequestHandler` instances to process requests, where each handler corresponds to an RPC method. The `handle` method returns a `HandlerResult`, which can be a `SingleResult` for one response or a `StreamResult` for a stream of responses.

## Data Models

The package includes Dart classes for A2A data structures (`AgentCard`, `Message`, `Task`, `SecurityScheme`). These are built with `freezed` and `json_serializable` to be immutable and support JSON serialization.
26 changes: 26 additions & 0 deletions packages/a2a_dart/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Copyright 2025 The Flutter Authors.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75 changes: 75 additions & 0 deletions packages/a2a_dart/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# A2A Dart

This package provides a Dart implementation of the A2A (Agent-to-Agent) protocol. It includes a client for interacting with A2A servers and a server framework for building A2A agents.

## Features

- **A2A Client**: A high-level client for communicating with A2A servers.
- **HTTP and SSE Transports**: Support for both standard request-response and streaming communication.
- **A2A Server**: A simple and extensible server framework.
- **Type-Safe Data Models**: Dart classes for all A2A data structures.
- **Web Compatible**: The client can be used in web applications.

## Installation

Add the following to your `pubspec.yaml` file:

```yaml
dependencies:
a2a_dart: ^0.1.0 # or the latest version
```

## Usage

### Client

```dart
import 'package:a2a_dart/a2a_dart.dart';
import 'package:logging/logging.dart';

void main() async {
final log = Logger('A2AClient');
// For streaming, use SseTransport.
final transport = SseTransport(url: 'http://localhost:8080', log: log);
final client = A2AClient(url: 'http://localhost:8080', transport: transport);

// Get the agent card.
final agentCard = await client.getAgentCard();
print('Agent: ${agentCard.name}');

// Create a new task.
final message = Message(
messageId: '1',
role: Role.user,
parts: [Part.text(text: 'Hello')],
);
final task = await client.createTask(message);
print('Created task: ${task.id}');

// Execute the task and stream the results.
try {
final stream = client.executeTask(task.id);
await for (final event in stream) {
print('Received event: ${event.type}');
}
} on A2AException catch (e) {
print('Error executing task: ${e.message}');
}
}
```

### Server

```dart
import 'package:a2a_dart/a2a_dart.dart';

void main() async {
final taskManager = TaskManager();
final server = A2AServer([
CreateTaskHandler(taskManager),
]);

await server.start();
print('Server started on port ${server.port}');
}
```
Loading
Loading