Summary
Build a new src/channels/a2a/ channel adapter implementing the A2A (Agent2Agent) Protocol v1.0.0, the unified open standard under the Linux Foundation (formed by the merger of IBM ACP and Google A2A, 2025).
This replaces the now-closed #214 (which targeted ACP v0.2.0, a defunct spec).
Spec: https://a2aproject.github.io/A2A/latest/specification/
Protocol binding: JSON-RPC 2.0 over HTTP + SSE (the standard JSON-RPC binding)
Problem
copilot-bridge currently has no standard-compliant external channel. The existing channels/acp/ (soon channels/copilot-bridge-ws-rpc/ per #231) is a custom internal WebSocket JSON-RPC protocol - well-suited for internal clients (kanban) but not interoperable with the broader A2A ecosystem.
An A2A channel would let any A2A-compliant client (other agents, external UIs, third-party tooling) interact with copilot-bridge agents without custom client code.
Proposed Solution
A new, clean implementation in src/channels/a2a/ that conforms to A2A v1.0.0. No shared code with channels/copilot-bridge-ws-rpc/.
Endpoints
| Method |
Endpoint |
Purpose |
GET |
/.well-known/agent.json |
Agent Card discovery |
POST |
/ |
JSON-RPC endpoint (all A2A operations) |
All A2A operations are multiplexed over a single JSON-RPC endpoint. SSE streaming is handled via Content-Type: text/event-stream on the same HTTP POST.
A2A Operations to implement
| Operation |
JSON-RPC Method |
Priority |
| Send message |
message/send |
P0 |
| Send streaming message |
message/stream |
P0 |
| Get task |
tasks/get |
P0 |
| Cancel task |
tasks/cancel |
P1 |
| Subscribe to task |
tasks/resubscribe |
P1 |
| Set push notification config |
tasks/pushNotificationConfig/set |
P2 |
| Get push notification config |
tasks/pushNotificationConfig/get |
P2 |
| List tasks |
tasks/list |
P2 |
Agent Card (.well-known/agent.json)
Per A2A spec, served at /.well-known/agent.json per agent. Fields:
{
"name": "...",
"description": "...",
"url": "https://host/agents/{name}",
"version": "...",
"capabilities": {
"streaming": true,
"pushNotifications": true,
"stateTransitionHistory": false
},
"defaultInputModes": ["text/plain"],
"defaultOutputModes": ["text/plain"],
"skills": [...]
}
Task Lifecycle
Maps SDK session events to A2A task states:
| SDK event |
A2A task state |
| Session created |
submitted |
session.in_progress |
working |
session.idle |
completed |
session.error |
failed |
| Permission requested |
input-required |
| Permission resolved |
back to working |
Streaming (SSE)
message/stream returns Content-Type: text/event-stream. Events emitted:
TaskStatusUpdateEvent - task state transitions
TaskArtifactUpdateEvent - streaming text chunks (as Part with mediaType: text/plain)
- Tool call tracking via
Part.metadata (trajectory data: tool name, input, output)
Permission Approval (HITL)
When the SDK requests a permission:
- Task transitions to
input-required
await_request in the Task object carries the permission details
- Client sends
message/send with the approval/denial to resume
- Task transitions back to
working
Push Notifications
When tasks/pushNotificationConfig/set is called, bridge registers the webhook URL. On task state transitions, bridge POSTs StreamResponse to the webhook.
The client (kanban) can register a webhook and disconnect - bridge will POST when the task needs attention (input-required, completed, failed).
Multi-turn Sessions
Each A2A task has a contextId. Subsequent messages with the same contextId are routed to the same underlying copilot session. Maps directly to the bridge's existing session-per-channel model.
What This Enables for Kanban
- Kanban sends a prompt via
message/stream, SSE stream stays open
- Agent streams thoughts/tool calls via
TaskArtifactUpdateEvent with trajectory metadata
- When agent needs approval: task goes
input-required, kanban renders approval UI
- Kanban resumes via
message/send with approval
- On disconnect: kanban calls
tasks/resubscribe to reattach to stream
- If kanban was offline: push notification fires, kanban calls
tasks/get to hydrate
- Agent can also use a
write_card_update skill to push richer semantic updates directly to the card
Implementation Notes
- Clean implementation - no shared code with
channels/copilot-bridge-ws-rpc/
channels/copilot-bridge-ws-rpc/ remains for internal clients; A2A channel is for external/ecosystem clients
- Auth: HTTP
Authorization: Bearer <token> per agent, same pattern as WS channel
- One HTTP server per A2A platform config entry (like the WS channel)
channels/copilot-bridge-ws-rpc/ is the eventual deprecation candidate once this covers all use cases
Spec References
Supersedes
Closes #214 (targeted ACP v0.2.0 - now defunct, merged into A2A)
Reported By
Agent (automated) - ACP/A2A conformance review + protocol research, 2026-05-22
Summary
Build a new
src/channels/a2a/channel adapter implementing the A2A (Agent2Agent) Protocol v1.0.0, the unified open standard under the Linux Foundation (formed by the merger of IBM ACP and Google A2A, 2025).This replaces the now-closed #214 (which targeted ACP v0.2.0, a defunct spec).
Spec: https://a2aproject.github.io/A2A/latest/specification/
Protocol binding: JSON-RPC 2.0 over HTTP + SSE (the standard JSON-RPC binding)
Problem
copilot-bridge currently has no standard-compliant external channel. The existing
channels/acp/(soonchannels/copilot-bridge-ws-rpc/per #231) is a custom internal WebSocket JSON-RPC protocol - well-suited for internal clients (kanban) but not interoperable with the broader A2A ecosystem.An A2A channel would let any A2A-compliant client (other agents, external UIs, third-party tooling) interact with copilot-bridge agents without custom client code.
Proposed Solution
A new, clean implementation in
src/channels/a2a/that conforms to A2A v1.0.0. No shared code withchannels/copilot-bridge-ws-rpc/.Endpoints
GET/.well-known/agent.jsonPOST/All A2A operations are multiplexed over a single JSON-RPC endpoint. SSE streaming is handled via
Content-Type: text/event-streamon the same HTTP POST.A2A Operations to implement
message/sendmessage/streamtasks/gettasks/canceltasks/resubscribetasks/pushNotificationConfig/settasks/pushNotificationConfig/gettasks/listAgent Card (
.well-known/agent.json)Per A2A spec, served at
/.well-known/agent.jsonper agent. Fields:{ "name": "...", "description": "...", "url": "https://host/agents/{name}", "version": "...", "capabilities": { "streaming": true, "pushNotifications": true, "stateTransitionHistory": false }, "defaultInputModes": ["text/plain"], "defaultOutputModes": ["text/plain"], "skills": [...] }Task Lifecycle
Maps SDK session events to A2A task states:
submittedsession.in_progressworkingsession.idlecompletedsession.errorfailedinput-requiredworkingStreaming (SSE)
message/streamreturnsContent-Type: text/event-stream. Events emitted:TaskStatusUpdateEvent- task state transitionsTaskArtifactUpdateEvent- streaming text chunks (asPartwithmediaType: text/plain)Part.metadata(trajectory data: tool name, input, output)Permission Approval (HITL)
When the SDK requests a permission:
input-requiredawait_requestin the Task object carries the permission detailsmessage/sendwith the approval/denial to resumeworkingPush Notifications
When
tasks/pushNotificationConfig/setis called, bridge registers the webhook URL. On task state transitions, bridge POSTsStreamResponseto the webhook.The client (kanban) can register a webhook and disconnect - bridge will POST when the task needs attention (input-required, completed, failed).
Multi-turn Sessions
Each A2A task has a
contextId. Subsequent messages with the samecontextIdare routed to the same underlying copilot session. Maps directly to the bridge's existing session-per-channel model.What This Enables for Kanban
message/stream, SSE stream stays openTaskArtifactUpdateEventwith trajectory metadatainput-required, kanban renders approval UImessage/sendwith approvaltasks/resubscribeto reattach to streamtasks/getto hydratewrite_card_updateskill to push richer semantic updates directly to the cardImplementation Notes
channels/copilot-bridge-ws-rpc/channels/copilot-bridge-ws-rpc/remains for internal clients; A2A channel is for external/ecosystem clientsAuthorization: Bearer <token>per agent, same pattern as WS channelchannels/copilot-bridge-ws-rpc/is the eventual deprecation candidate once this covers all use casesSpec References
Supersedes
Closes #214 (targeted ACP v0.2.0 - now defunct, merged into A2A)
Reported By
Agent (automated) - ACP/A2A conformance review + protocol research, 2026-05-22