a2acalling 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md ADDED
@@ -0,0 +1,66 @@
1
+ # Agent Runbook (A2A for OpenClaw)
2
+
3
+ This file is the operational source of truth for AI agents working in this repository.
4
+
5
+ ## GitHub Access
6
+
7
+ GitHub token is stored in `.env` (gitignored). Load it before git operations:
8
+
9
+ ```bash
10
+ export GH_TOKEN=$(grep GH_TOKEN .env | cut -d= -f2)
11
+ git remote set-url origin https://${GH_TOKEN}@github.com/onthegonow/A2A_for_OpenClaw.git
12
+ ```
13
+
14
+ Or use `gh` CLI which reads `GH_TOKEN` automatically.
15
+
16
+ ## Project Structure
17
+
18
+ ```
19
+ a2acalling/
20
+ ├── bin/cli.js # CLI entry point (a2a command)
21
+ ├── src/
22
+ │ ├── index.js # Main library export
23
+ │ ├── lib/
24
+ │ │ ├── tokens.js # Token storage & validation
25
+ │ │ └── client.js # Outbound A2A client
26
+ │ └── routes/
27
+ │ └── federation.js # Express routes for /api/federation
28
+ ├── docs/
29
+ │ └── protocol.md # Protocol specification
30
+ └── .env # Secrets (gitignored)
31
+ ```
32
+
33
+ ## Development Commands
34
+
35
+ ```bash
36
+ # Test CLI
37
+ node bin/cli.js help
38
+ node bin/cli.js create --name "Test" --expires 1h
39
+
40
+ # Test library
41
+ node -e "const a2a = require('./src'); console.log(a2a.version)"
42
+ ```
43
+
44
+ ## Key Design Decisions
45
+
46
+ 1. **Token format**: `a2a://<host>/<token>` - simple, copy-pasteable
47
+ 2. **Permission presets**: `chat-only` (default), `tools-read`, `tools-write`
48
+ 3. **Disclosure levels**: `public`, `minimal` (default), `none`
49
+ 4. **Rate limits**: 10/min, 100/hr, 1000/day per token
50
+ 5. **Storage**: JSON file at `~/.config/openclaw/a2a-federation.json`
51
+
52
+ ## Integration Points
53
+
54
+ This package is designed to integrate with OpenClaw:
55
+
56
+ 1. **Gateway routes**: Mount `createRoutes()` at `/api/federation`
57
+ 2. **Agent tool**: Add `federation_call` tool using `A2AClient`
58
+ 3. **Commands**: Wire `/federation` commands to CLI functions
59
+
60
+ ## Commit Convention
61
+
62
+ Use conventional commits:
63
+ - `feat:` new features
64
+ - `fix:` bug fixes
65
+ - `docs:` documentation
66
+ - `refactor:` code changes without feature/fix
package/CLAUDE.md ADDED
@@ -0,0 +1,52 @@
1
+ # CLAUDE.md - A2A for OpenClaw
2
+
3
+ ## Quick Context
4
+
5
+ A2A Calling enables agent-to-agent communication across OpenClaw instances. Users create tokens with scoped permissions, share invite URLs, and remote agents can call in.
6
+
7
+ ## GitHub Access
8
+
9
+ ```bash
10
+ # Token in .env (gitignored)
11
+ source .env
12
+ # Or for git operations:
13
+ git remote set-url origin https://${GH_TOKEN}@github.com/onthegonow/A2A_for_OpenClaw.git
14
+ ```
15
+
16
+ ## What This Does
17
+
18
+ 1. **Token Management** - Create expiring tokens with permissions (chat-only/tools-read/tools-write)
19
+ 2. **Inbound Calls** - Express routes handle `/api/federation/invoke` from remote agents
20
+ 3. **Outbound Calls** - `A2AClient` calls remote agents via their invite URLs
21
+ 4. **Owner Notifications** - Configurable alerts when your agent gets called
22
+
23
+ ## Token Flow
24
+
25
+ ```
26
+ User: /federation create --name "Alice" --expires 7d
27
+ Bot: ✅ a2a://myhost.com/fed_abc123
28
+
29
+ User shares URL with Alice...
30
+
31
+ Alice's agent: POST /api/federation/invoke
32
+ Authorization: Bearer fed_abc123
33
+ {"message": "Hey, can you help?"}
34
+
35
+ Your agent responds within permission scope.
36
+ You get notified (if configured).
37
+ ```
38
+
39
+ ## Files to Know
40
+
41
+ - `src/lib/tokens.js` - All token CRUD + validation
42
+ - `src/lib/client.js` - `A2AClient` for outbound calls
43
+ - `src/routes/federation.js` - Express router (mount at `/api/federation`)
44
+ - `docs/protocol.md` - Full protocol spec
45
+
46
+ ## Testing
47
+
48
+ ```bash
49
+ node bin/cli.js create --name "Test" --expires 1h
50
+ node bin/cli.js list
51
+ node bin/cli.js revoke <id>
52
+ ```
package/README.md ADDED
@@ -0,0 +1,307 @@
1
+ # 🤝 A2A Calling
2
+
3
+ **Agent-to-Agent calling with OpenClaw support. Let your people talk to my people!**
4
+
5
+ [![npm version](https://img.shields.io/npm/v/a2acalling.svg)](https://www.npmjs.com/package/a2acalling)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ---
9
+
10
+ Your AI agent can now call other AI agents — across instances, with scoped permissions, strategic summaries, and owner notifications. Think of it as a phone system for agents.
11
+
12
+ ## ✨ Features
13
+
14
+ - 🔐 **Tiered permissions** — public (chat), friends (tools-read), family (tools-write)
15
+ - 📇 **Contact management** — save agents, track trust, link permissions
16
+ - 🧠 **Strategic summaries** — track what you got vs. gave, find mutual wins
17
+ - 🔔 **Owner notifications** — know when your agent gets called
18
+ - ⏱️ **Flexible tokens** — expiring or permanent, call limits optional
19
+ - 🚦 **Rate limiting** — 10/min, 100/hr, 1000/day built-in
20
+ - 🔄 **Multi-turn conversations** — continue threads across calls
21
+ - 💾 **Conversation history** — SQLite storage with context retrieval
22
+
23
+ ## 🚀 Quick Start
24
+
25
+ ### Create an invite for others to call your agent
26
+
27
+ ```bash
28
+ a2a create --name "My Agent" --owner "Your Name" --tier friends
29
+
30
+ # Output:
31
+ # 🤝 Your Name is inviting you to connect agents!
32
+ # Your agent can reach My Agent for: chat, web, files
33
+ # a2a://your-host.com:3001/fed_abc123xyz
34
+ ```
35
+
36
+ ### Call someone else's agent
37
+
38
+ ```bash
39
+ # Add them as a contact
40
+ a2a add "a2a://their-host.com/fed_xyz789" "Alice's Agent"
41
+
42
+ # Make a call
43
+ a2a call "Alice's Agent" "Hey! Want to collaborate on the federation protocol?"
44
+
45
+ # Or call directly
46
+ a2a call "a2a://their-host.com/fed_xyz789" "Hello!"
47
+ ```
48
+
49
+ ## 📦 Installation
50
+
51
+ ```bash
52
+ # Global CLI
53
+ npm install -g a2acalling
54
+
55
+ # As a library
56
+ npm install a2acalling
57
+ ```
58
+
59
+ ### For OpenClaw Users
60
+
61
+ ```bash
62
+ # Run the installer
63
+ npx a2acalling install
64
+
65
+ # Or clone and install
66
+ git clone https://github.com/onthegonow/A2A_for_OpenClaw.git
67
+ cd A2A_for_OpenClaw
68
+ npm install
69
+ node scripts/install-openclaw.js
70
+ ```
71
+
72
+ ## 🎯 Permission Tiers
73
+
74
+ | Tier | Alias | What They Can Access |
75
+ |------|-------|---------------------|
76
+ | `public` | `chat-only` | Conversation only |
77
+ | `friends` | `tools-read` | Chat + web, files, calendar (read) |
78
+ | `family` | `tools-write` | Full tool access (careful!) |
79
+
80
+ Customize tiers in `~/.config/openclaw/a2a-config.json`:
81
+
82
+ ```json
83
+ {
84
+ "tiers": {
85
+ "friends": {
86
+ "topics": ["chat", "web", "files", "calendar"],
87
+ "disclosure": "minimal"
88
+ }
89
+ }
90
+ }
91
+ ```
92
+
93
+ ## 📇 Contact Management
94
+
95
+ ```bash
96
+ # Add a contact
97
+ a2a add "a2a://host/token" "Alice"
98
+
99
+ # View contact details (shows trust level from YOUR token to them)
100
+ a2a show "Alice"
101
+
102
+ # Ping to check availability
103
+ a2a ping "Alice"
104
+
105
+ # Link a token you created FOR them
106
+ a2a link "Alice" tok_abc123
107
+
108
+ # List all contacts
109
+ a2a contacts
110
+
111
+ # Remove a contact
112
+ a2a rm "Alice"
113
+ ```
114
+
115
+ ## 🧠 Strategic Summaries
116
+
117
+ Every call generates an owner-context summary that tracks the exchange:
118
+
119
+ ```json
120
+ {
121
+ "exchange": {
122
+ "weGot": ["learned about their developer tools project"],
123
+ "weGave": ["shared our A2A federation work"],
124
+ "balance": "even",
125
+ "fair": true
126
+ },
127
+ "mutualValue": {
128
+ "found": true,
129
+ "opportunities": ["potential integration partnership"],
130
+ "alignment": "connects to owner's interest in agent collaboration"
131
+ },
132
+ "trust": {
133
+ "assessment": "appropriate",
134
+ "recommendation": "maintain",
135
+ "pattern": "genuine partner, collaborative tone"
136
+ }
137
+ }
138
+ ```
139
+
140
+ Summaries are **private** — never shared with the caller.
141
+
142
+ ## 🔧 CLI Reference
143
+
144
+ ### Token Management
145
+
146
+ ```bash
147
+ a2a create [options] # Create an invite token
148
+ --name, -n <name> # Token/contact name
149
+ --owner, -o <name> # Your name (for invite)
150
+ --tier, -t <tier> # public|friends|family
151
+ --topics <list> # Custom topic list
152
+ --expires, -e <duration> # 1h|1d|7d|30d|never (default: never)
153
+ --max-calls <n> # Limit total calls (default: unlimited)
154
+ --notify <level> # all|summary|none
155
+
156
+ a2a list # List your tokens
157
+ a2a revoke <id> # Revoke a token
158
+ a2a quickstart # Interactive setup
159
+ ```
160
+
161
+ ### Calling
162
+
163
+ ```bash
164
+ a2a call <target> <message> # Call an agent
165
+ --timeout <seconds> # Response timeout (default: 60)
166
+ --context <text> # Add context for the call
167
+
168
+ a2a ping <target> # Check if agent is available
169
+ ```
170
+
171
+ ### Server
172
+
173
+ ```bash
174
+ a2a serve [options] # Start federation server
175
+ --port, -p <port> # Port (default: 3001)
176
+ ```
177
+
178
+ ## 📡 Protocol
179
+
180
+ Tokens use the `a2a://` URI scheme:
181
+
182
+ ```
183
+ a2a://<hostname>:<port>/<token>
184
+ ```
185
+
186
+ ### API Endpoints
187
+
188
+ | Method | Path | Description |
189
+ |--------|------|-------------|
190
+ | `GET` | `/api/federation/status` | Check federation support |
191
+ | `GET` | `/api/federation/ping` | Health check with auth |
192
+ | `POST` | `/api/federation/invoke` | Call the agent |
193
+
194
+ ### Invoke Request
195
+
196
+ ```json
197
+ {
198
+ "message": "Hello!",
199
+ "caller": { "name": "Agent Name", "owner": "Owner Name" },
200
+ "conversation_id": "optional-for-continuation",
201
+ "timeout_seconds": 60
202
+ }
203
+ ```
204
+
205
+ ### Invoke Response
206
+
207
+ ```json
208
+ {
209
+ "success": true,
210
+ "conversation_id": "conv_123",
211
+ "response": "Agent's response",
212
+ "can_continue": true,
213
+ "tokens_remaining": null
214
+ }
215
+ ```
216
+
217
+ ## 🔌 Library Usage
218
+
219
+ ### Making Calls (Client)
220
+
221
+ ```javascript
222
+ const { A2AClient } = require('a2acalling');
223
+
224
+ const client = new A2AClient({
225
+ caller: { name: 'My Agent', owner: 'My Name' }
226
+ });
227
+
228
+ // Call via invite URL
229
+ const response = await client.call(
230
+ 'a2a://their-host.com/fed_token123',
231
+ 'Can you help me with something?'
232
+ );
233
+
234
+ // Continue the conversation
235
+ const followUp = await client.call(
236
+ 'a2a://their-host.com/fed_token123',
237
+ 'Thanks! One more question...',
238
+ { conversationId: response.conversation_id }
239
+ );
240
+ ```
241
+
242
+ ### Receiving Calls (Server)
243
+
244
+ ```javascript
245
+ const { createRoutes, TokenStore } = require('a2acalling');
246
+ const express = require('express');
247
+
248
+ const app = express();
249
+ app.use(express.json());
250
+
251
+ app.use('/api/federation', createRoutes({
252
+ tokenStore: new TokenStore(),
253
+
254
+ async handleMessage(message, context) {
255
+ // context.permissions, context.caller, context.conversationId
256
+ return {
257
+ text: await yourAgent.respond(message, context),
258
+ canContinue: true
259
+ };
260
+ },
261
+
262
+ async notifyOwner({ caller, message }) {
263
+ await notify(`🤝 ${caller.name} called your agent`);
264
+ }
265
+ }));
266
+
267
+ app.listen(3001);
268
+ ```
269
+
270
+ ## 🛡️ Security
271
+
272
+ - **Rate limiting**: 10 calls/min, 100/hr, 1000/day per token
273
+ - **Timeout bounds**: 5-300 seconds
274
+ - **Token scoping**: Permissions baked in at creation
275
+ - **Revocation**: Instant via `a2a revoke`
276
+
277
+ ## 🌍 Environment Variables
278
+
279
+ | Variable | Description |
280
+ |----------|-------------|
281
+ | `A2A_HOSTNAME` | Hostname for invite URLs (required for creates) |
282
+ | `A2A_PORT` | Server port (default: 3001) |
283
+ | `A2A_CONFIG_DIR` | Config directory (default: `~/.config/openclaw`) |
284
+
285
+ ## 🤝 Philosophy
286
+
287
+ Federation is **cooperative AND adversarial**. Each agent maximizes value for their owner — but the best outcomes are mutual wins.
288
+
289
+ Your agent should:
290
+ 1. **Protect your interests** — track what you're giving vs. getting
291
+ 2. **Find mutual value** — look for wins on both sides
292
+ 3. **Build relationships** — trust is earned over time
293
+ 4. **Stay strategic** — not every caller is a friend
294
+
295
+ ## 📚 Links
296
+
297
+ - [OpenClaw](https://github.com/openclaw/openclaw) — The AI agent framework
298
+ - [Protocol Spec](docs/protocol.md) — Full protocol documentation
299
+ - [Discord](https://discord.gg/clawd) — Community chat
300
+
301
+ ## 📄 License
302
+
303
+ MIT — go build something cool.
304
+
305
+ ---
306
+
307
+ *Let your people talk to my people.* 🤝
package/SKILL.md ADDED
@@ -0,0 +1,122 @@
1
+ ---
2
+ name: a2a
3
+ description: "Agent-to-agent federation for OpenClaw. Create tokens to let remote agents call yours as a subagent with scoped permissions. Use when setting up cross-instance agent communication, creating federation tokens, managing remote agent access, or calling other OpenClaw agents."
4
+ metadata:
5
+ {
6
+ "openclaw":
7
+ {
8
+ "emoji": "🤝",
9
+ "requires": { "bins": ["node"] },
10
+ "install":
11
+ [
12
+ {
13
+ "id": "npm",
14
+ "kind": "node",
15
+ "package": "a2acalling",
16
+ "bins": ["a2a"],
17
+ "label": "Install A2A Calling (npm)",
18
+ },
19
+ ],
20
+ "routes": "/api/federation",
21
+ "tools": ["federation_call"],
22
+ },
23
+ }
24
+ ---
25
+
26
+ # A2A Federation
27
+
28
+ Enable agent-to-agent communication across OpenClaw instances.
29
+
30
+ ## Commands
31
+
32
+ ### Create Token
33
+
34
+ User says: `/federation create`, "create a federation token", "let another agent call me"
35
+
36
+ ```bash
37
+ a2a create --name "NAME" --expires DURATION --permissions LEVEL
38
+ ```
39
+
40
+ Options:
41
+ - `--name, -n` — Token label
42
+ - `--expires, -e` — `1h`, `1d`, `7d`, `30d`, `never` (default: `1d`)
43
+ - `--permissions, -p` — `chat-only`, `tools-read`, `tools-write` (default: `chat-only`)
44
+ - `--disclosure, -d` — `public`, `minimal`, `none` (default: `minimal`)
45
+ - `--notify` — `all`, `summary`, `none` (default: `all`)
46
+
47
+ Reply with the invite URL: `a2a://hostname/fed_xxxxx`
48
+
49
+ ### List Tokens
50
+
51
+ ```bash
52
+ a2a list
53
+ ```
54
+
55
+ ### Revoke Token
56
+
57
+ ```bash
58
+ a2a revoke TOKEN_ID
59
+ ```
60
+
61
+ ### Add Remote Agent
62
+
63
+ When user shares an invite URL:
64
+
65
+ ```bash
66
+ a2a add "a2a://host/token" "Agent Name"
67
+ ```
68
+
69
+ ## Calling Remote Agents
70
+
71
+ When task delegation to a known remote agent would help, or user asks to contact a federated agent:
72
+
73
+ ```javascript
74
+ // Use federation_call tool
75
+ federation_call({
76
+ endpoint: "a2a://host/token",
77
+ message: "Your question here",
78
+ conversation_id: "optional-for-continuity"
79
+ })
80
+ ```
81
+
82
+ ## Handling Incoming Calls
83
+
84
+ When receiving a federation call, the agent operates within the token's permission scope:
85
+
86
+ | Permission | Allowed |
87
+ |------------|---------|
88
+ | `chat-only` | Conversation only. No tools, files, memory. |
89
+ | `tools-read` | Chat + read-only tools |
90
+ | `tools-write` | Chat + read/write tools |
91
+
92
+ Apply disclosure level:
93
+ - `public` — Share any non-private info
94
+ - `minimal` — Direct answers only, no owner context
95
+ - `none` — Confirm capability only
96
+
97
+ ## Owner Notifications
98
+
99
+ When `notify: all`, send to owner:
100
+
101
+ ```
102
+ 🤝 Federation call received
103
+
104
+ From: [Caller] ([host])
105
+ Token: "[name]" (expires [date])
106
+
107
+ ---
108
+ [Transcript]
109
+ ---
110
+
111
+ 📊 [N] calls | Expires in [time]
112
+ ```
113
+
114
+ Owner can reply to inject into the conversation.
115
+
116
+ ## Rate Limits
117
+
118
+ Per token: 10/min, 100/hr, 1000/day
119
+
120
+ ## Protocol Reference
121
+
122
+ See [docs/protocol.md](docs/protocol.md) for full specification.