Избранное
a2a-php-sdk
Клиентский и серверный SDK протокола A2A 1.0.0 для PHP 8.4 — все 11 операций поверх JSON-RPC, REST и gRPC, потоковая передача через SSE и gRPC, прогон официального A2A TCK.
- PHP 8.4
- A2A 1.0.0
- JSON-RPC
- HTTP+JSON / REST
- gRPC (OpenSwoole)
- SSE
- Protocol Buffers
- Symfony HttpClient
- PHPStan level 8
- Docker
Проблема
A2A (Agent2Agent) — открытый протокол, сейчас проект Linux Foundation, через который агенты на разных фреймворках вызывают друг друга. Версия 1.0.0 вышла 12 марта 2026 года. Официальные SDK есть для Python, JavaScript, Java, Go, .NET и Rust — для PHP нет. PHP-реализации на Packagist по состоянию на сентябрь 2026 года поддерживают протокол 0.3.0.
В итоге бэкенды на Symfony и чистом PHP не могут ни опубликовать агента в экосистему A2A, ни вызвать оттуда чужого, не написав формат обмена руками.
Что это
- Клиент и сервер в одном пакете, PHP 8.4+, без зависимости от Laravel/Illuminate.
- Классы сообщений сгенерированы из официального
a2a.protov1.0.0. CI перегенерирует их и сравнивает байт в байт, SHA-256 proto записан в репозитории. - Все 11 операций —
sendMessage,sendStreamingMessage,getTask,listTasks,cancelTask,subscribeToTask, четыре операции с настройками push-уведомлений иgetExtendedAgentCard— поверх JSON-RPC, HTTP+JSON/REST и gRPC, через одни и те же типизированные методы клиента. - Потоковая передача через SSE и gRPC идёт через один сервис задач и одну валидацию.
$client = new Client(
new HttpTransport(HttpClient::create(), $endpoint, jsonRpc: true),
new CallOptions(timeoutSeconds: 30, headers: ['Authorization' => 'Bearer '.$token]),
);
$response = $client->sendMessage($request);
foreach ($client->sendStreamingMessage($request) as $event) {
$consumer->accept($event);
}
Серверная часть
Агент — это один интерфейс, Executor, который отдаёт обновления статуса и артефактов задачи. SDK сам создаёт задачу, записывает сообщение пользователя, выставляет WORKING, хранит историю и потоковые события и доставляет вебхуки.
- Файловое хранилище работает с блокировками и атомарной заменой. В записях есть идентификатор вызывающего и tenant, поэтому задача видна только тому, кто её создал.
- Долгие задачи идут через
returnImmediatelyи воркеры, вызывающиеProcessor::workOnce(). - Вебхуки доставляются по принципу at least once, только по HTTPS и на явно разрешённые хосты; адреса частных сетей по умолчанию заблокированы.
- Нативный gRPC-сервер работает на OpenSwoole 26.2+ и выключен, пока его не включить.
Безопасные умолчания
- Обнаружение Agent Card ограничивает размер ответа и блокирует адреса частных сетей. Эндпоинт из недоверенной карточки автоматически не выбирается.
- Вызовы клиента не повторяются автоматически: повтор
sendMessage()может выполнить работу дважды, поэтому политику повторов решает приложение. - TLS у gRPC-клиента включён по умолчанию. Тесты покрывают TLS и mTLS на всех трёх биндингах, включая недоверенный CA, неверное имя сервера и отсутствующий клиентский сертификат.
Совместимость — точными цифрами
make tck собирает официальный a2a-tck 1.0.0 из зафиксированных исходников и прогоняет его на всех трёх транспортах. Неизменённый набор даёт 244 passed, 3 failed, 18 skipped.
Все три падения — одно требование, CORE-SEND-003, на каждом транспорте. Оно говорит, что неподдерживаемый тип данных MUST возвращать ContentTypeNotSupportedError, но в определении требования внутри TCK ожидаемая ошибка не указана, и правильный ответ засчитывается как провал. SDK возвращает именно требуемую ошибку: -32005 для JSON-RPC, HTTP 415 для REST, INVALID_ARGUMENT с CONTENT_TYPE_NOT_SUPPORTED для gRPC. Дефект заведён в официальном репозитории — a2a-tck#202; с исправлением из PR #203 прогон даёт 247 passed, 18 skipped.
CI пропускает ровно эти три задокументированных падения и падает на любом новом. Это не заявление о полной сертификации по TCK.
Выпуск
- CI на каждый pull request, push и тег: установка по lock-файлу и аудит уязвимостей, модульные и сетевые тесты, PHPStan level 8, PSR-12, проверка перегенерации протокола и установка ZIP-архива в чистый проект без gRPC-расширений.
- Опубликован как v1.0.0 на Packagist под Apache-2.0:
composer require vbcherepanov/a2a-php-sdk. - Включён в официальный список community SDK протокола A2A (принято 7 октября 2026).
- Для приложений на Symfony маршруты, воркеры, хранилище Doctrine и Messenger даёт парный a2a-symfony-bundle.
Выводы
- Набор тестов совместимости — тоже софт. Разбор причины падения показал дефект в тесте, а не в SDK, и правильным ходом было сообщить о нём в официальный репозиторий, а не подгонять SDK под неверную проверку.
- Генерация типов из официального proto и проверка перегенерации в CI убирают целый класс расхождений между спецификацией и написанными руками классами.