Multi-Purpose Repository:
- @drew-foxall/a2a-ai-sdk-adapter - NPM package for bridging Vercel AI SDK agents with the A2A protocol
- Agent Examples - 19 working A2A agent examples demonstrating the adapter in action
- Cloudflare Workers - 23 example workers demonstrating multi-agent orchestration via Service Bindings
Built with Vercel AI SDK v6, TypeScript, and @drew-foxall/a2a-js-sdk
Deployment Layer: Workers use Hono for HTTP routing (see Separation Patterns)
npm install @drew-foxall/a2a-ai-sdk-adapter
# or
pnpm add @drew-foxall/a2a-ai-sdk-adapterimport { ToolLoopAgent } from "ai";
import { openai } from "@ai-sdk/openai";
import { A2AAdapter } from "@drew-foxall/a2a-ai-sdk-adapter";
// Create your AI agent
const agent = new ToolLoopAgent({
model: openai("gpt-4o"),
instructions: "You are a helpful assistant",
tools: {}, // Add your tools here
});
// Wrap it for A2A protocol
const adapter = new A2AAdapter(agent, {
mode: "stream", // or "generate"
});
// Use with A2A server (Hono, Express, etc.)
// See packages/a2a-ai-sdk-adapter/README.md for detailsFull Documentation: packages/a2a-ai-sdk-adapter/README.md
# Clone and install
git clone https://github.com/drew-foxall/a2a-js-sdk-examples.git
cd a2a-js-sdk-examples
pnpm install
# Build all packages
pnpm build
# Start a demo agent (use Ctrl+C to stop)
pnpm agent:hello-world
# Opens on http://localhost:41244
# Available agents:
# pnpm agent:movie # Movie search agent
# pnpm agent:coder # Code generation
# pnpm agent:dice # Dice rolling
# pnpm agent:github # GitHub integration
# pnpm agent:analytics # Chart generation
# pnpm agent:currency # Currency conversion
# pnpm agent:weather # Weather forecasts
# pnpm agent:airbnb # Airbnb search
# pnpm agent:planner # Travel planning (multi-agent)Test with A2A Inspector:
Recommended - Local Inspector:
# Terminal 1: Start inspector
pnpm inspector
# Terminal 2: Start agent
pnpm agent:hello-world
# Browser: http://127.0.0.1:5001
# Connect: http://localhost:41244Quick Commands:
pnpm inspector # Start local inspector
pnpm inspector:stop # Stop inspector
pnpm inspector:logs # View logs
pnpm start-testing # Interactive mode📖 Testing Guides:
- Local Testing - Full local dev with Redis/Upstash
- Inspector Setup - Local A2A Inspector (Docker)
- Test Workflow - Step-by-step: Start agents + use A2A Inspector
- Quick Start (3 min) - Get testing immediately
- Full Testing Guide - Comprehensive scenarios
Local Infrastructure (for Redis-dependent workers):
pnpm local:up # Start Redis + Upstash adapter
pnpm local:down # Stop infrastructure
pnpm local:status # Check service healtha2a-js-sdk-examples/
├── packages/
│ └── a2a-ai-sdk-adapter/ # 📦 NPM Package
│ ├── src/
│ │ ├── adapter.ts # Core A2AAdapter class
│ │ ├── adapter.test.ts # Vitest unit tests
│ │ └── index.ts # Package exports
│ ├── package.json # @drew-foxall/a2a-ai-sdk-adapter
│ └── README.md # API documentation
│
├── examples/
│ ├── agents/ # 🤖 19 Working Agents (Protocol-Agnostic)
│ │ ├── src/agents/
│ │ │ ├── hello-world/ # Simplest example
│ │ │ ├── dice-agent/ # Tool usage
│ │ │ ├── github-agent/ # External APIs (Octokit)
│ │ │ ├── analytics-agent/ # Artifacts (PNG charts)
│ │ │ ├── currency-agent/ # Real-time data
│ │ │ ├── movie-agent/ # Multi-turn conversations
│ │ │ ├── coder/ # Code generation
│ │ │ ├── content-editor/ # Text processing
│ │ │ ├── expense-agent/ # Multi-step forms
│ │ │ ├── image-generator/ # DALL-E integration
│ │ │ ├── adversarial/ # Security testing
│ │ │ ├── auth-agent/ # OAuth/OIDC flows
│ │ │ ├── code-review/ # Code analysis
│ │ │ ├── contact-extractor/ # Data extraction
│ │ │ ├── content-planner/ # Content outlines
│ │ │ ├── local-llm-chat/ # Local LLM support
│ │ │ ├── mcp-registry/ # MCP server registry
│ │ │ ├── number-game/ # Pure logic (no LLM)
│ │ │ └── travel-planner-multiagent/
│ │ │ ├── weather-agent/ # Weather specialist
│ │ │ ├── airbnb-agent/ # MCP integration
│ │ │ └── planner/ # Multi-agent orchestrator
│ │ └── package.json
│ │
│ ├── workers/ # ☁️ 23 Cloudflare Workers
│ │ ├── shared/ # Shared utilities (a2a-workers-shared)
│ │ │ ├── worker-config.ts # Framework-agnostic config
│ │ │ ├── hono-adapter.ts # createA2AHonoWorker()
│ │ │ ├── agent-card.ts # buildAgentCard()
│ │ │ ├── types.ts # Environment types
│ │ │ └── utils.ts # Model providers
│ │ ├── hello-world/ # Simple agent worker
│ │ ├── dice-agent/ # Tool-using worker
│ │ ├── dice-agent-durable/ # Durable (Workflow DevKit)
│ │ ├── currency-agent/ # External API worker
│ │ ├── weather-agent/ # Specialist (Service Binding)
│ │ ├── airbnb-agent/ # MCP-powered specialist
│ │ ├── airbnb-mcp-server/ # MCP server worker
│ │ ├── travel-planner/ # Orchestrator worker
│ │ ├── travel-planner-durable/ # Durable orchestrator
│ │ ├── image-generator-durable/ # Durable image gen
│ │ └── README.md # Workers documentation
│ │
│ └── TESTING_WITH_A2A_INSPECTOR.md # Testing guide
│
├── docker-compose.local.yml # Local Redis + Upstash adapter
├── LOCAL_TESTING.md # Local testing guide
├── turbo.json # Turborepo configuration
├── pnpm-workspace.yaml # pnpm monorepo setup
└── README.md # This file
All examples demonstrate different adapter capabilities:
| Agent | Purpose | Mode | Key Feature |
|---|---|---|---|
| Hello World | Simplest A2A agent | Generate | Baseline example |
| Dice Agent | Simple tool usage | Stream | Tool calling |
| Currency Agent | Real-time data | Stream | Frankfurter API |
| Analytics Agent | Artifact generation | Generate | PNG charts |
| Coder | Code generation | Stream | Real-time artifacts |
| Content Editor | Text processing | Generate | Simple transforms |
| Agent | Purpose | Mode | Key Feature |
|---|---|---|---|
| GitHub Agent | GitHub API integration | Stream | Octokit API |
| Movie Agent | Multi-turn conversations | Generate | TMDB API |
| Image Generator | Image creation | Generate | DALL-E API |
| Agent | Purpose | Mode | Key Feature |
|---|---|---|---|
| Expense Agent | Multi-step forms | Stream | State management |
| Contact Extractor | Data extraction | Generate | Structured output |
| Content Planner | Content outlines | Generate | Planning |
| Code Review | Code analysis | Stream | Static analysis |
| Adversarial | Security testing | Stream | Prompt injection |
| Auth Agent | OAuth/OIDC flows | Generate | Authentication |
| Local LLM Chat | Local LLM support | Stream | Ollama/LM Studio |
| Number Game | Pure logic agent | N/A | No LLM required |
| Agent | Purpose | Mode | Key Feature |
|---|---|---|---|
| Weather Agent | Weather data | Stream | Open-Meteo API |
| Airbnb Agent | MCP integration | Stream | Real Airbnb data |
| Travel Planner | Multi-agent orchestration | Stream | Agent networks |
Start agents individually (see package.json for all available commands):
# Core examples
pnpm agent:hello-world # Simplest example
pnpm agent:dice # Dice rolling with tools
pnpm agent:coder # Code generation (streaming)
# External APIs
pnpm agent:github # GitHub integration
pnpm agent:movie # Movie search (TMDB)
pnpm agent:analytics # Chart generation
# Multi-agent
pnpm agent:weather # Weather specialist
pnpm agent:airbnb # Airbnb specialist
pnpm agent:planner # Travel orchestratorProcess Management:
- Start:
pnpm agent:<name> - Stop:
Ctrl+Cin the terminal - Multiple agents: Open separate terminals for each agent
Testing: See examples/TESTING_WITH_A2A_INSPECTOR.md for comprehensive testing instructions.
Deploy A2A agents to Cloudflare Workers for globally distributed agents.
# 1. Set your OpenAI API key as a secret
pnpm --filter a2a-hello-world-worker exec wrangler secret put OPENAI_API_KEY
# 2. Deploy a single worker
pnpm worker:deploy:hello-world
# 3. Deploy all workers
pnpm workers:deploy:all# Local Development (with wrangler dev)
pnpm worker:hello-world # Hello World agent
pnpm worker:dice # Dice Agent
pnpm worker:currency # Currency Agent
pnpm worker:weather # Weather Agent (specialist)
pnpm worker:airbnb-agent # Airbnb Agent (specialist)
pnpm worker:planner # Travel Planner (orchestrator)
pnpm worker:airbnb-mcp-server # Airbnb MCP Server
# Deploy to Cloudflare
pnpm worker:deploy:hello-world
pnpm worker:deploy:dice
pnpm worker:deploy:currency
pnpm worker:deploy:weather
pnpm worker:deploy:airbnb-agent
pnpm worker:deploy:planner
pnpm worker:deploy:airbnb-mcp-server
pnpm workers:deploy:all # Deploy everythingexamples/workers/
├── shared/ # Shared utilities (a2a-workers-shared)
│ ├── worker-config.ts # Framework-agnostic configuration
│ ├── hono-adapter.ts # createA2AHonoWorker() factory
│ ├── agent-card.ts # buildAgentCard() utility
│ ├── types.ts # Environment type definitions
│ ├── utils.ts # Model provider setup
│ └── redis.ts # Redis task store utilities
├── hello-world/ # Simple A2A agent
├── dice-agent/ # Tool-using agent
├── dice-agent-durable/ # Durable version (Workflow DevKit)
├── currency-agent/ # External API integration
├── weather-agent/ # Specialist (Service Binding target)
├── airbnb-agent/ # MCP-powered specialist
├── airbnb-mcp-server/ # MCP server as a Worker
├── travel-planner/ # Multi-agent orchestrator
├── travel-planner-durable/ # Durable orchestrator (Workflow DevKit)
└── image-generator-durable/ # Durable image generation
The Travel Planner demonstrates a multi-agent architecture using Cloudflare Service Bindings for secure, private worker-to-worker communication:
┌─────────────────────────────────────────────────────────────┐
│ PUBLIC INTERNET │
└─────────────────────────┬───────────────────────────────────┘
│
▼
┌───────────────────────┐
│ Travel Planner │ ◄── Public A2A endpoint
│ (Orchestrator) │
└───────────┬───────────┘
│
┌─────────────┴─────────────┐
│ Service Bindings │ ◄── Private, no public access
│ (Internal Only) │
▼ ▼
┌───────────────────┐ ┌───────────────────┐
│ Weather Agent │ │ Airbnb Agent │
│ (Specialist) │ │ (Specialist) │
└───────────────────┘ └─────────┬─────────┘
│
▼
┌───────────────────┐
│ Airbnb MCP Server │
│ (Internal Only) │
└───────────────────┘
Key Features:
- Service Bindings: Private worker-to-worker calls (no public URLs)
- INTERNAL_ONLY flag: Specialist workers reject public requests
- Zero network latency: Service Bindings bypass the public internet
Each worker needs an OPENAI_API_KEY secret:
# Set secret for each worker
pnpm --filter a2a-hello-world-worker exec wrangler secret put OPENAI_API_KEY
pnpm --filter a2a-dice-agent-worker exec wrangler secret put OPENAI_API_KEY
pnpm --filter a2a-currency-agent-worker exec wrangler secret put OPENAI_API_KEY
pnpm --filter a2a-weather-agent-worker exec wrangler secret put OPENAI_API_KEY
pnpm --filter a2a-airbnb-agent-worker exec wrangler secret put OPENAI_API_KEY
pnpm --filter a2a-travel-planner-worker exec wrangler secret put OPENAI_API_KEY
# Verify secrets are set
pnpm --filter a2a-hello-world-worker exec wrangler secret listFor local development, create a .dev.vars file in each worker directory:
# examples/workers/hello-world/.dev.vars
OPENAI_API_KEY=sk-your-key-hereThen run with wrangler dev:
cd examples/workers/hello-world
pnpm dev # Starts on http://localhost:8787Zod schemas don't work correctly in Cloudflare Workers due to bundling issues. The workers use explicit JSON Schema objects instead:
// ❌ Doesn't work in Workers (Zod schema gets stripped)
const schema = z.object({ location: z.string() });
// ✅ Works in Workers (explicit JSON Schema)
const schemaSymbol = Symbol.for("vercel.ai.schema");
const schema = {
[schemaSymbol]: true,
jsonSchema: {
type: "object",
properties: { location: { type: "string" } },
required: ["location"],
},
validate: async (value) => ({ success: true, value }),
};See examples/workers/weather-agent/src/index.ts for a complete example.
📖 Full Documentation: examples/workers/README.md
All agents use the same A2AAdapter class with explicit mode switching:
import { ToolLoopAgent } from "ai";
import { A2AAdapter } from "@drew-foxall/a2a-ai-sdk-adapter";
import { openai } from "@ai-sdk/openai";
// 1. Create AI SDK agent (protocol-agnostic)
const agent = new ToolLoopAgent({
model: openai("gpt-4o"),
instructions: "You are a helpful assistant",
tools: { /* your tools */ },
});
// 2. Wrap with A2A adapter (mode: 'stream' or 'generate')
const executor = new A2AAdapter(agent, {
mode: "stream", // Real-time text streaming
parseArtifacts: (text) => {
// Extract artifacts from text (optional)
return [];
},
});
// 3. Use with A2A server
import { A2AHonoApp } from "@drew-foxall/a2a-js-sdk/hono";
import { serve } from "@hono/node-server";
const app = new A2AHonoApp({ card: agentCard, executor });
serve({ fetch: app.fetch, port: 41244 });| Mode | Use When | Capabilities |
|---|---|---|
stream |
Long responses, code generation, real-time updates | ✅ Text streaming ✅ Real-time artifact parsing ✅ Post-completion artifacts |
generate |
Quick responses, API-style interactions | ✅ Single awaited response ✅ Post-completion artifacts |
See: packages/a2a-ai-sdk-adapter/README.md for full API documentation
# Run all tests (adapter + all agents)
pnpm test
# Run tests in watch mode
pnpm test:watch
# Run with coverage
pnpm test:coverage
# Run tests for adapter only
pnpm turbo run test --filter @drew-foxall/a2a-ai-sdk-adapter
# Run tests for specific agent
pnpm test src/agents/hello-world/agent.test.ts
# Run all tests for an agent (agent + tools)
pnpm test src/agents/analytics-agent/Test Coverage:
- Adapter: 11 unit tests (configuration, loggers, modes, type safety)
- Durable Adapter: 11 tests for
DurableA2AAdapterwith Workflow DevKit - Agents: 84 tests across 21 test files
- Each agent has
agent.test.ts(ToolLoopAgent behavior) - Agents with utilities have
tools.test.ts(pure functions) - All tests follow AGENT_TEST_PRINCIPLES.md
- Each agent has
- Telemetry: 17 E2E tests for OpenTelemetry integration
- Uses real OTEL SDK with in-memory exporter
- Tests span creation, attributes, events, trace context
- Verifies A2A semantic conventions (
AgentAttributes,SpanNames)
- Shared Workers: Tests for
worker-config.tsandagent-card.ts - Test Quality: All test files have ratio < 1.0x (test lines < source lines)
- Type Safety: No
as anyoras unknown ascasts in test files
📖 Documentation:
- Agent Test Principles - Testing standards and patterns
- Full Testing Guide - Comprehensive testing documentation
- Telemetry Guide - Pluggable telemetry with OpenTelemetry E2E tests
- Worker Testing Guide - Hybrid E2E testing with AI SDK and MSW mocks
-
Start an agent:
pnpm agent:hello-world
-
Start local inspector:
pnpm inspector(runs in Docker) -
Enter:
http://localhost:41244 -
Test interactively!
Full Guide: examples/TESTING_WITH_A2A_INSPECTOR.md
- Node.js: ≥ 24.0.0 (Active LTS - Krypton)
- pnpm: ≥ 10.0.0 (v10.23.0, installed automatically via
packageManagerfield) - OpenAI API Key: For running examples
# 1. Clone repository
git clone https://github.com/drew-foxall/a2a-js-sdk-examples.git
cd a2a-js-sdk-examples
# 2. Install dependencies
pnpm install
# 3. Build all packages
pnpm build
# 4. Set up environment variables
cp examples/agents/.env.example examples/agents/.env
# Edit .env and add your OPENAI_API_KEY
# 5. Start an agent
pnpm agents:hello-world# Build
pnpm build # Build all packages (with caching)
# Development
pnpm dev # Start all agents in parallel
# Testing
pnpm test # Run all unit tests
pnpm test:watch # Run tests in watch mode
# Code Quality
pnpm typecheck # Type checking
pnpm lint # Lint all code
pnpm lint:fix # Auto-fix lint issues
pnpm format # Check formatting
pnpm format:write # Auto-format code
# Individual Agents
pnpm agents:hello-world # Start hello-world agent
pnpm agents:coder # Start coder agent
# ... etc (see package.json for all commands)Powered by: Turborepo for parallel execution and caching
- Separation Patterns - Agent vs Worker architecture, compliance checklist
- Platform Portability - Deploy same agent on Cloudflare, Vercel, AWS
- Telemetry Guide - Pluggable observability with OpenTelemetry
- A2AAdapter API - Adapter class API reference
- A2A AI Provider - Use A2A agents as AI SDK models
- Quick Start - Get testing in 3 minutes
- Full Testing Guide - Comprehensive testing scenarios
- Local Infrastructure - Redis + Upstash for local development
- A2A Protocol - Official A2A protocol documentation
- Vercel AI SDK - AI SDK v6 documentation
- AI SDK Testing - Official testing guide
- @drew-foxall/a2a-js-sdk - A2A JS SDK (Hono fork)
- a2a-samples - Official Python/JavaScript examples
- a2a-inspector - Web-based A2A agent inspector
- a2a-js - Official A2A JavaScript SDK
- @drew-foxall/a2a-js-sdk - A2A JS SDK with Hono support (this project's dependency)
Contributions welcome! Areas of interest:
- New Agent Examples: Add agents demonstrating new patterns
- Adapter Improvements: Enhance
A2AAdapterfunctionality - Documentation: Improve guides and API docs
- Testing: Add more unit/integration tests
- Provider Support: Examples using other AI SDK providers (Anthropic, Google, etc.)
# 1. Fork and clone
git clone https://github.com/YOUR_USERNAME/a2a-js-sdk-examples.git
# 2. Create a branch
git checkout -b feature/my-new-feature
# 3. Make changes and test
pnpm build
pnpm test
pnpm lint
# 4. Commit and push
git commit -m "feat: add my new feature"
git push origin feature/my-new-feature
# 5. Open a Pull RequestStyle Guide: We use Biome for linting/formatting. Run pnpm lint:fix and pnpm format:write before committing.
Apache 2.0 - See LICENSE for details
- Vercel AI SDK Team - For the excellent AI SDK v6
- A2A Project - For the Agent2Agent protocol
- Hono - For the lightweight web framework
- Total TypeScript - For strict TypeScript configurations
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- A2A Protocol: a2a.plus
- AI SDK: ai-sdk.dev
Good luck 🦊