{
  "id": "2026-04-27-google-agent-sdk-a2a-2bf5970827",
  "scope": "redkey",
  "source_of_truth": "repo",
  "source_path": "docs/specs/2026-04-27-google-agent-sdk-a2a.md",
  "source_kind": "markdown",
  "visibility": "internal",
  "renderer_id": "design_doc.dreamborn-forge.generated.v1",
  "design_system": "dreamborn-design-system:forge",
  "generated_at": "2026-05-09T13:00:55.682Z",
  "artifact_type": "design_doc",
  "schema_version": "design_doc.generated.v1",
  "title": "Google Agent SDK + A2A Integration",
  "summary": "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...",
  "format_source": "markdown",
  "sections": [
    {
      "title": "Google Agent SDK + A2A Integration",
      "level": 1,
      "body": "**Date:** 2026-04-27  \n**Status:** Spec approved — implementation plan at `docs/plans/2026-04-27-a2a-gateway.md`\n\n---"
    },
    {
      "title": "What This Builds",
      "level": 2,
      "body": "Two independent components, sequenced:\n\n1. **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.\n\n2. **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.\n\n---"
    },
    {
      "title": "Why A2A",
      "level": 2,
      "body": "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.\n\nMaking RedKey A2A-compliant means:\n- Any A2A-compatible platform can discover and dispatch work to RedKey agents\n- RedKey agents become first-class citizens in the broader agent ecosystem\n- Directly enables marketplace: agents get an Agent Card, they're listed, they're callable\n- Callers don't know or care that execution is on Hedera\n\n---"
    },
    {
      "title": "Overview",
      "level": 3,
      "body": "```\nExternal A2A Caller\n  │\n  │ POST /  (JSON-RPC 2.0)\n  ▼\nA2A Gateway (Express, port 3002, VPS)\n  │\n  ├── message/send   → INSERT agent_tasks (UUID) + POST task.available to role topic (HCS)\n  ├── tasks/get      → SELECT agent_tasks.status → map to A2A TaskState\n  └── tasks/cancel   → UPDATE agent_tasks.status=cancelled + POST task.cancelled (HCS)\n\nRole topic (HCS)\n  │ task.available{task_id: <uuid>}\n  ▼\nAgent runner (poll_and_claim) → enriches from agent_tasks → executes → task.complete\n  │\n  ▼\nagent_tasks.status = complete  →  GetTask returns TASK_STATE_COMPLETED\n```"
    },
    {
      "title": "Endpoints",
      "level": 3,
      "body": "| Endpoint | Method | Description |\n|---|---|---|\n| `/.well-known/agent.json` | GET | Agent Card — capabilities, skills, auth |\n| `/` | POST | JSON-RPC 2.0 — all A2A methods |"
    },
    {
      "title": "A2A Methods (v1)",
      "level": 3,
      "body": "| Method | What it does |\n|---|---|\n| `message/send` | Accept task → create `agent_tasks` row (UUID) → post `task.available` to HCS role topic |\n| `tasks/get` | Look up `agent_tasks` by `id` → map status to A2A TaskState |\n| `tasks/cancel` | Update `agent_tasks.status=cancelled` |\n\nStreaming (`message/sendStream`), push notifications, and multi-turn contexts are **out of scope for v1**."
    },
    {
      "title": "Task Lifecycle Mapping",
      "level": 3,
      "body": "| `agent_tasks.status` | A2A TaskState |\n|---|---|\n| `created` | `submitted` |\n| `assigned` | `submitted` |\n| `in_progress` | `working` |\n| `complete` | `completed` |\n| `blocked` / `failed` | `failed` |\n| `cancelled` | `canceled` |"
    },
    {
      "title": "Agent Card",
      "level": 3,
      "body": "Dynamically generated from Supabase at startup (cached, refreshed every 5 minutes). Pulls agent definitions and role slugs. Skills map 1:1 to RedKey roles.\n\n```json\n{\n  \"name\": \"RedKey Agent Platform\",\n  \"description\": \"Multi-agent workflow platform. Submit tasks to specialized AI workers via role-based routing on Hedera HCS.\",\n  \"url\": \"https://<A2A_GATEWAY_URL>\",\n  \"version\": \"1.0.0\",\n  \"capabilities\": {\n    \"streaming\": false,\n    \"pushNotifications\": false,\n    \"extendedAgentCard\": false\n  },\n  \"defaultInputModes\": [\"text/plain\"],\n  \"defaultOutputModes\": [\"text/plain\"],\n  \"skills\": [\n    { \"id\": \"software-development\", \"name\": \"Software Development\", \"description\": \"Code, features, bug fixes. Delivered by Quinn.\" },\n    { \"id\": \"code-review\", \"name\": \"Code Review\", \"description\": \"PR review, architecture critique. Delivered by Vikram.\" },\n    { \"id\": \"architecture\", \"name\": \"Architecture\", \"description\": \"System design, ADR decisions. Delivered by Vikram.\" },\n    { \"id\": \"business-analysis\", \"name\": \"Business Analysis\", \"description\": \"Requirements, specs, PRDs. Delivered by Priya.\" },\n    { \"id\": \"product-management\", \"name\": \"Product Management\", \"description\": \"Project planning, task breakdown. Delivered by Mindy.\" },\n    { \"id\": \"quality-assurance\", \"name\": \"Quality Assurance\", \"description\": \"Test plans, QA verification. Delivered by Luna.\" },\n    { \"id\": \"ux-design\", \"name\": \"UX Design\", \"description\": \"User flows, component specs, UX documentation. Delivered by Zara.\" },\n    { \"id\": \"crm\", \"name\": \"CRM Operations\", \"description\": \"Lead enrichment, sequence management. Delivered by Arlo.\" }\n  ],\n  \"securitySchemes\": {\n    \"bearerAuth\": { \"type\": \"http\", \"scheme\": \"bearer\" }\n  },\n  \"security\": [{ \"bearerAuth\": [] }]\n}\n```"
    },
    {
      "title": "Skill → Role Routing",
      "level": 3,
      "body": "```js\nconst SKILL_TO_ROLE = {\n  'software-development': 'developer',\n  'code-review':          'reviewer',\n  'architecture':         'architect',\n  'business-analysis':    'ba',\n  'product-management':   'pm',\n  'quality-assurance':    'qa',\n  'ux-design':            'ux',\n  'crm':                  'crm',\n};\n```\n\nIf no skill specified: default to `coordinator`. If skill unknown: return 400.\n\nThe 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."
    },
    {
      "title": "Authentication",
      "level": 3,
      "body": "Bearer token. Single static token in `A2A_GATEWAY_TOKEN` env var. All endpoints except `/.well-known/agent.json` require it.\n\nNo client registration in v1. One token = one access level = full write access to all roles. Per-client token scoping is Phase 2."
    },
    {
      "title": "Task ID Strategy (v1)",
      "level": 3,
      "body": "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`.\n\n**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.\n\n**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."
    },
    {
      "title": "Runner Modification Required",
      "level": 3,
      "body": "`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.\n\nTwo changes needed:\n1. `_enrich_from_agent_tasks`: add UUID path that queries by `id` column\n2. `_post_task_complete`: for UUID tasks, update `agent_tasks.status = 'complete'` in Supabase (ensures `GetTask` sees the completion)"
    },
    {
      "title": "Configuration (env vars)",
      "level": 3,
      "body": "| Var | Description |\n|---|---|\n| `A2A_GATEWAY_TOKEN` | Bearer token for incoming A2A requests |\n| `A2A_GATEWAY_URL` | Public URL of this gateway (put in Agent Card) |\n| `A2A_GATEWAY_PORT` | HTTP port (default: 3002) |\n| `A2A_DEFAULT_CLIENT_ID` | client_id stamped on externally-submitted tasks (default: `a2a`) |\n| `REDKEY_SUPABASE_URL` | Already on VPS |\n| `REDKEY_SUPABASE_SECRET_KEY` | Already on VPS |\n| `HEDERA_OPERATOR_ID` | Already on VPS |\n| `HEDERA_OPERATOR_KEY` | Already on VPS |\n| `HEDERA_NETWORK` | Already on VPS (testnet) |\n\n---"
    },
    {
      "title": "Phase 2: Gemini Workspace Worker",
      "level": 2,
      "body": "A Python agent using Google ADK that handles Google Workspace tasks via Gemini.\n\n**Why:** DreamBorn is deeply Google-integrated (Drive, Docs, Gmail, Calendar via `scripts/lib/google-dreamborn.js`). A Gemini-powered worker has native advantages on Workspace tasks and costs less than Sonnet for routine operations.\n\n**Design sketch:**\n- New role: `roles.workspace` (new HCS topic needed)\n- New agent: `agents/gemini-workspace/runner.py` — uses `google-adk` + `google-generativeai` instead of Claude CLI\n- ADK `Agent` configured with `gemini-2.5-flash` model + Google Workspace tools (Drive, Docs, Gmail, Calendar)\n- Same HCS claim mechanics (`hedera_queue.py`) — only execution layer changes\n- Deployed as `redkey-gemini-workspace.timer` on VPS\n\n**Implementation plan:** separate doc when Phase 1 is live.\n\n---"
    },
    {
      "title": "Open Questions",
      "level": 2,
      "body": "| # | Question | Decision |\n|---|---|---|\n| OQ-1 | Should Agent Card skill list be DB-driven (auto-generated from `roles` table) or static? | Static for v1 — roles rarely change, dynamic generation adds complexity |\n| OQ-2 | What client_id to stamp on A2A tasks? | `a2a` by default, configurable per deployment via `A2A_DEFAULT_CLIENT_ID` |\n| OQ-3 | Do we need CORS headers for browser-based A2A callers? | Add permissive CORS for v1, tighten in Phase 2 |\n| OQ-4 | Rate limiting? | Not in v1 — add nginx rate limiting at deployment if needed |"
    }
  ],
  "html_path": "artifacts/2026-04-27-google-agent-sdk-a2a-2bf5970827.html",
  "json_path": "artifacts/2026-04-27-google-agent-sdk-a2a-2bf5970827.json"
}