Summary
Implement the A2A (Agent-to-Agent) protocol so codeoid sessions are discoverable and callable by other A2A-compatible systems (SwarmClaw, other Claude Code instances, custom orchestrators). Each session exposes an Agent Card describing its capabilities, and a task endpoint that accepts A2A task requests.
Background
The A2A protocol (https://a2a-protocol.org) is an emerging standard for agent interoperability. As the ecosystem of AI coding agents grows, being able to receive delegated tasks from an orchestrator — or to discover and call other agents — is a strategic capability. Codeoid's identity-first architecture maps cleanly onto A2A's api_key auth method, with ZeroID tokens as the credential.
Proposed Design
Agent Card (GET /.well-known/agent.json or per-session)
```typescript
interface AgentCard {
name: string
description: string
version: string
protocolVersion: string // e.g. "0.3.0"
apiEndpoint: string // URL of the A2A task endpoint
capabilities: AgentCapability[]
skills: AgentSkill[]
authMethods: ['zeroid' | 'api_key']
supportsStreaming: boolean
supportsAsync: boolean
tags: string[]
}
```
Two modes:
- Daemon-level card (
/api/a2a/agent.json): describes the daemon and lists all available sessions
- Session-level card (
/api/a2a/sessions/:name/agent.json): describes a specific session and its configured capabilities
Task endpoint
```
POST /api/a2a/sessions/:name/tasks
```
Accepts an A2A task object, creates a Task (once the task board lands), sends the prompt to the named session, and returns task status. Supports SSE streaming for supportsStreaming=true callers.
Auth
A2A callers authenticate with a ZeroID token in Authorization: Bearer <token>. The token is verified the same way as WebSocket connections — same auth.ts middleware. This means the full ZeroID scope model (session:send required) applies to A2A callers automatically.
Discovery endpoint
```
GET /api/a2a/agents # list all sessions as A2A agent cards
GET /api/a2a/agents/:name # card for a specific session
```
Task status
```
GET /api/a2a/tasks/:id # poll task status
DELETE /api/a2a/tasks/:id # cancel task
```
Registration with SwarmClaw (optional)
When swarmclaw.gatewayUrl is set in config, the daemon can register its agent cards with a SwarmClaw OpenClaw gateway at startup, making codeoid sessions discoverable within that SwarmClaw deployment.
Changes required
- New
src/daemon/a2a/ directory
agent-card.ts — generate cards from session config + capabilities
task-handler.ts — accept A2A task, create Task, return status
routes.ts — mount /api/a2a/* on ctx.httpServer
src/daemon/server.ts — register a2a frontend module
Acceptance criteria
Related
- Task board (A2A tasks map onto board Tasks)
- Session capabilities (used to populate Agent Card skills)
- ZeroID auth (
src/daemon/auth.ts — reuse as-is)
Summary
Implement the A2A (Agent-to-Agent) protocol so codeoid sessions are discoverable and callable by other A2A-compatible systems (SwarmClaw, other Claude Code instances, custom orchestrators). Each session exposes an Agent Card describing its capabilities, and a task endpoint that accepts A2A task requests.
Background
The A2A protocol (https://a2a-protocol.org) is an emerging standard for agent interoperability. As the ecosystem of AI coding agents grows, being able to receive delegated tasks from an orchestrator — or to discover and call other agents — is a strategic capability. Codeoid's identity-first architecture maps cleanly onto A2A's
api_keyauth method, with ZeroID tokens as the credential.Proposed Design
Agent Card (
GET /.well-known/agent.jsonor per-session)```typescript
interface AgentCard {
name: string
description: string
version: string
protocolVersion: string // e.g. "0.3.0"
apiEndpoint: string // URL of the A2A task endpoint
capabilities: AgentCapability[]
skills: AgentSkill[]
authMethods: ['zeroid' | 'api_key']
supportsStreaming: boolean
supportsAsync: boolean
tags: string[]
}
```
Two modes:
/api/a2a/agent.json): describes the daemon and lists all available sessions/api/a2a/sessions/:name/agent.json): describes a specific session and its configured capabilitiesTask endpoint
```
POST /api/a2a/sessions/:name/tasks
```
Accepts an A2A task object, creates a
Task(once the task board lands), sends the prompt to the named session, and returns task status. Supports SSE streaming forsupportsStreaming=truecallers.Auth
A2A callers authenticate with a ZeroID token in
Authorization: Bearer <token>. The token is verified the same way as WebSocket connections — sameauth.tsmiddleware. This means the full ZeroID scope model (session:send required) applies to A2A callers automatically.Discovery endpoint
```
GET /api/a2a/agents # list all sessions as A2A agent cards
GET /api/a2a/agents/:name # card for a specific session
```
Task status
```
GET /api/a2a/tasks/:id # poll task status
DELETE /api/a2a/tasks/:id # cancel task
```
Registration with SwarmClaw (optional)
When
swarmclaw.gatewayUrlis set in config, the daemon can register its agent cards with a SwarmClaw OpenClaw gateway at startup, making codeoid sessions discoverable within that SwarmClaw deployment.Changes required
src/daemon/a2a/directoryagent-card.ts— generate cards from session config + capabilitiestask-handler.ts— accept A2A task, create Task, return statusroutes.ts— mount/api/a2a/*onctx.httpServersrc/daemon/server.ts— register a2a frontend moduleAcceptance criteria
GET /api/a2a/agentslists all sessions as A2A agent cardsGET /api/a2a/agents/:namereturns card for a specific sessionPOST /api/a2a/sessions/:name/taskscreates and runs a taskGET /api/a2a/tasks/:idfor async pollingDELETE /api/a2a/tasks/:idcancels a running taskRelated
src/daemon/auth.ts— reuse as-is)