Skip to content

feat(a2a): spec-compliant A2A v0.3 implementation#1

Merged
SimplyLiz merged 3 commits intomainfrom
feature/a2a-spec-compliance
Mar 31, 2026
Merged

feat(a2a): spec-compliant A2A v0.3 implementation#1
SimplyLiz merged 3 commits intomainfrom
feature/a2a-spec-compliance

Conversation

@SimplyLiz
Copy link
Copy Markdown
Collaborator

Summary

Rewrites the A2A module to fully comply with the Agent2Agent v0.3 specification. The previous implementation was a functional skeleton with REST-style routing, missing methods, incomplete types, and no auth — this brings it to spec.

What changed

Server (src/a2a/server.ts)

  • Single JSON-RPC 2.0 endpoint replacing REST-style URL routing
  • Agent card served at /.well-known/agent-card.json (spec-correct path, with legacy fallback)
  • All spec methods: message/send, message/stream (SSE), tasks/get, tasks/cancel, tasks/resubscribe, push notification config CRUD, agent/getAuthenticatedExtendedCard
  • Authentication middleware via authenticate callback
  • contextFactory option for wiring real AgentContext into task execution
  • Push notifications with Bearer/Basic auth to registered webhooks
  • Multi-turn conversations via input-required state + task resume
  • Spec-compliant JSON-RPC error codes (1001–1009)
  • CORS headers

Client (src/a2a/client.ts)

  • Agent card discovery with canonical + legacy path fallback
  • Both polling and SSE streaming execution
  • Multi-turn support via onInputRequired callback
  • Bearer token and API key authentication
  • cancelA2ATask() helper
  • onStreamEvent callback for real-time streaming updates

Types (src/a2a/types.ts — new file)

  • Complete spec-compliant type definitions
  • AgentCard with kind, protocolVersion, provider, securitySchemes, security
  • All Part types: TextPart, FilePart (bytes + uri variants), DataPart
  • All task states including auth-required and rejected
  • Proper A2AArtifact schema with id, name, description, parts, metadata
  • contextId for conversation session grouping
  • A2AErrorCodes enum

Agent Card (src/a2a/agent-card.ts)

  • ToAgentCardOptions for configuring provider info, security schemes, streaming, push notifications
  • All optional card fields supported

Issues addressed

# Issue Fix
1 Wrong well-known path (agent.jsonagent-card.json) Canonical path + legacy fallback
2 REST routing instead of JSON-RPC dispatch Single POST / endpoint, method-based dispatch
3 Missing tasks/cancel Implemented with not-cancelable error for terminal tasks
4 No SSE streaming (message/stream) Full SSE with heartbeat, subscriber mgmt, resubscribe
5 No tasks/resubscribe Implemented — reconnect to in-progress task streams
6 No push notification CRUD set/get/list/delete on tasks/pushNotificationConfig/*
7 Wrong artifact schema Spec-compliant: id, name, description, parts, metadata
8 No JSON-RPC errors Full error codes (parse, method-not-found, task-not-found, etc.)
9 Agent Card missing fields kind, protocolVersion, provider, securitySchemes, security
10 No multi-turn support input-required state + task resume via message/send with taskId
11 No contextId Server-generated or client-provided context grouping
12 No authentication Server middleware + client Bearer/API key support
13 No FilePart support TextPart, FilePart (bytes/uri), DataPart all typed
14 Mock AgentContext in server contextFactory config option for real agent wiring
15 Missing task states Added auth-required, rejected
16 Client doesn't support streaming SSE stream reader with artifact collection
17 No extended agent card agent/getAuthenticatedExtendedCard method

Test plan

  • All 313 existing tests pass (no regressions)
  • 17 A2A-specific tests covering:
    • Agent card generation with required + optional fields
    • Agent card served at canonical and legacy well-known paths
    • message/send via JSON-RPC
    • tasks/get with artifact verification
    • tasks/cancel + not-cancelable error
    • JSON-RPC error for unknown methods
    • JSON-RPC error for task-not-found
    • Authentication enforcement (reject without token, accept with token)
    • contextId propagation
    • Artifact schema compliance
    • Push notification config CRUD
    • Client round-trip (card discovery → task execution → result)
    • Client with authentication
    • Client SSE streaming
  • TypeScript strict mode passes
  • ESLint passes (0 errors)

🤖 Generated with Claude Code

SimplyLiz and others added 3 commits March 28, 2026 11:39
Rewrites the A2A module to align with the Agent2Agent v0.3 specification.

Server:
- JSON-RPC 2.0 dispatch on single endpoint (replaces REST-style URL routing)
- Agent card at /.well-known/agent-card.json (with legacy path fallback)
- All spec methods: message/send, message/stream, tasks/get, tasks/cancel,
  tasks/resubscribe, push notification config CRUD, getAuthenticatedExtendedCard
- SSE streaming with heartbeat and subscriber management
- Authentication middleware support
- contextFactory for wiring real AgentContext into task execution
- Push notifications with Bearer/Basic auth
- Multi-turn via input-required state and task resume
- Proper JSON-RPC error codes (1001-1009)
- CORS support

Client:
- Agent card discovery with canonical + legacy path fallback
- Polling and SSE streaming execution modes
- Multi-turn with onInputRequired callback
- Bearer and API key authentication
- cancelA2ATask helper
- onStreamEvent callback for streaming updates

Types:
- Full spec-compliant type definitions in dedicated types.ts
- AgentCard with kind, protocolVersion, provider, securitySchemes, security
- All Part types: TextPart, FilePart (bytes + uri), DataPart
- All task states: submitted, working, input-required, auth-required,
  completed, failed, canceled, rejected
- Artifact schema with id, name, description, parts, metadata
- contextId for conversation grouping
- A2A error codes enum

Agent Card:
- ToAgentCardOptions for provider, security, streaming, push notifications
- Spec-compliant card generation with all optional fields

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix resource leak in client SSE streaming: rewrite recursive .then()
  chain as async while loop with reader.cancel() in finally block (#2, #5)
- Add timeout enforcement in server executeTask via Promise.race using
  agent.timeoutMs (default 5min), prevents tasks hanging forever (#3)
- Add skillId-based agent resolution: when MessageSendParams includes
  skillId, server matches against agent capabilities; returns
  UNSUPPORTED_SKILL (1004) error if no match (#4)
- Add test for multi-agent skill routing (correct dispatch + error case)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@SimplyLiz SimplyLiz merged commit 1e8f5d6 into main Mar 31, 2026
2 checks passed
@SimplyLiz SimplyLiz deleted the feature/a2a-spec-compliance branch March 31, 2026 23:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant