Google Agent SDK + A2A Integration
Google Agent SDK + A2A Integration Date: 2026 04 27 Status: Spec approved — implementation plan at docs/plans/2026 04 27 a2a gateway.md What This Builds Two independent components, sequenced: 1. A2A Gateway (Phase 1) — an HTTP server that makes RedKey agents callable from any A2A compatible platform. External callers discover agents via Agent Card, submit ta...
Date: 2026-04-27
Status: Spec approved — implementation plan at docs/plans/2026-04-27-a2a-gateway.md
---
Two independent components, sequenced:
1. A2A Gateway (Phase 1) — an HTTP server that makes RedKey agents callable from any A2A-compatible platform. External callers discover agents via Agent Card, submit tasks via JSON-RPC, and poll for results. RedKey's HCS pull model handles execution transparently.
2. Gemini Workspace Worker (Phase 2) — a Google ADK-powered worker that handles Google Workspace tasks (Drive, Docs, Gmail, Calendar) using Gemini instead of Claude. Follows the same HCS claim mechanics as existing workers.
---
A2A (Agent2Agent) is an open protocol under the Linux Foundation, adopted by 150+ orgs including Google, Microsoft, Salesforce, SAP, and ServiceNow. v1.0 released Q1 2026.
- Any A2A-compatible platform can discover and dispatch work to RedKey agents
- RedKey agents become first-class citizens in the broader agent ecosystem
- Directly enables marketplace: agents get an Agent Card, they're listed, they're callable
- Callers don't know or care that execution is on Hedera
---
``` External A2A Caller │ │ POST / (JSON-RPC 2.0) ▼ A2A Gateway (Express, port 3002, VPS) │ ├── message/send → INSERT agent_tasks (UUID) + POST task.available to role topic (HCS) ├── tasks/get → SELECT agent_tasks.status → map to A2A TaskState └── tasks/cancel → UPDATE agent_tasks.status=cancelled + POST task.cancelled (HCS)
Role topic (HCS) │ task.available{task_id: <uuid>} ▼ Agent runner (poll_and_claim) → enriches from agent_tasks → executes → task.complete │ ▼ agent_tasks.status = complete → GetTask returns TASK_STATE_COMPLETED ```
| Endpoint | Method | Description |
|---|---|---|
| /.well-known/agent.json | GET | Agent Card — capabilities, skills, auth |
| / | POST | JSON-RPC 2.0 — all A2A methods |
| Method | What it does |
|---|---|
| message/send | Accept task → create agent_tasks row (UUID) → post task.available to HCS role topic |
| tasks/get | Look up agent_tasks by id → map status to A2A TaskState |
| tasks/cancel | Update agent_tasks.status=cancelled |
Streaming (message/sendStream), push notifications, and multi-turn contexts are out of scope for v1.
| agent_tasks.status | A2A TaskState |
|---|---|
| created | submitted |
| assigned | submitted |
| in_progress | working |
| complete | completed |
| blocked / failed | failed |
| cancelled | canceled |
Dynamically generated from Supabase at startup (cached, refreshed every 5 minutes). Pulls agent definitions and role slugs. Skills map 1:1 to RedKey roles.
```json { "name": "RedKey Agent Platform", "description": "Multi-agent workflow platform. Submit tasks to specialized AI workers via role-based routing on Hedera HCS.", "url": "https://<A2A_GATEWAY_URL>", "version": "1.0.0", "capabilities": { "streaming": false, "pushNotifications": false, "extendedAgentCard": false }, "defaultInputModes": ["text/plain"], "defaultOutputModes": ["text/plain"], "skills": [ { "id": "software-development", "name": "Software Development", "description": "Code, features, bug fixes. Delivered by Quinn." }, { "id": "code-review", "name": "Code Review", "description": "PR review, architecture critique. Delivered by Vikram." }, { "id": "architecture", "name": "Architecture", "description": "System design, ADR decisions. Delivered by Vikram." }, { "id": "business-analysis", "name": "Business Analysis", "description": "Requirements, specs, PRDs. Delivered by Priya." }, { "id": "product-management", "name": "Product Management", "description": "Project planning, task breakdown. Delivered by Mindy." }, { "id": "quality-assurance", "name": "Quality Assurance", "description": "Test plans, QA verification. Deliv
``js
const SKILL_TO_ROLE = {
'software-development': 'developer',
'code-review': 'reviewer',
'architecture': 'architect',
'business-analysis': 'ba',
'product-management': 'pm',
'quality-assurance': 'qa',
'ux-design': 'ux',
'crm': 'crm',
};
``
If no skill specified: default to coordinator. If skill unknown: return 400.
The skill is read from the A2A message metadata field skill. If absent, check the message text for the first matching skill keyword (loose match on skill description terms). Coordinator is the safe default.
Bearer token. Single static token in A2A_GATEWAY_TOKEN env var. All endpoints except /.well-known/agent.json require it.
No client registration in v1. One token = one access level = full write access to all roles. Per-client token scoping is Phase 2.
External A2A tasks use UUID (crypto.randomUUID()) as task ID — no HCS topic created. Tasks stored in agent_tasks with id = <uuid>, topic_id = null. Workers pick them up via HCS task.available message pointing to the UUID, then enrich from agent_tasks by id.
Why not create an HCS topic per A2A task: Topic creation costs ~$0.01 USD per topic and adds ~2s latency. For external tasks that may come in volume, this is too expensive for v1.
On-chain record: task.available is still posted to the role topic. The claim, execution result, and completion are not on-chain for v1 A2A tasks. On-chain audit for A2A tasks is Phase 2.
agents/shared/runner.py:_enrich_from_agent_tasks currently only enriches tasks with 0.0. prefix task IDs (Phase 3 HCS topics). UUID tasks from A2A gateway need the same enrichment via agent_tasks.id column.
Two changes needed:
1. _enrich_from_agent_tasks: add UUID path that queries by id column
2. _post_task_complete: for UUID tasks, update agent_tasks.status = 'complete' in Supabase (ensures GetTask sees the completion)