@clawcrony/claw-crony 1.2.4 → 1.3.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/CHANGELOG.md +107 -0
- package/CONFIG.md +341 -0
- package/README.md +147 -18
- package/dist/index.js +509 -164
- package/dist/src/ephemeral-token.d.ts +3 -1
- package/dist/src/ephemeral-token.js +7 -2
- package/dist/src/history.d.ts +44 -0
- package/dist/src/history.js +119 -0
- package/dist/src/hub-match.js +1 -1
- package/dist/src/hub-registration.js +1 -1
- package/dist/src/types.d.ts +4 -1
- package/openclaw.plugin.json +46 -18
- package/package.json +43 -27
- package/scripts/a2a-diagnose.ps1 +15 -0
- package/scripts/a2a-diagnose.sh +22 -0
- package/scripts/a2a-history.ps1 +21 -0
- package/scripts/a2a-history.sh +9 -0
- package/scripts/a2a-match.ps1 +16 -0
- package/scripts/a2a-match.sh +13 -0
- package/scripts/a2a-peers.ps1 +1 -0
- package/scripts/a2a-peers.sh +4 -0
- package/scripts/a2a-send.ps1 +23 -0
- package/scripts/a2a-send.sh +14 -0
- package/scripts/a2a-update.ps1 +3 -0
- package/scripts/a2a-update.sh +6 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
## [1.3.0] - 2026-05-08
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- Declared OpenClaw startup activation and tool contracts in `openclaw.plugin.json` for OpenClaw 2026.5.2 discovery.
|
|
11
|
+
- Registered `gateway_start` and `gateway_stop` hooks so Hub registration and presence updates participate in the OpenClaw Gateway lifecycle.
|
|
12
|
+
- Added validation and regression coverage for encrypted handshake temporary inbound tokens.
|
|
13
|
+
- Added gateway methods `a2a.match`, `a2a.peers`, and `a2a.history` for script-friendly Hub matching, peer inspection, and request history queries.
|
|
14
|
+
- Added PowerShell and Bash helper scripts under `scripts/` for match, send, peers, history, diagnose, and update flows.
|
|
15
|
+
- Added redacted JSONL request history for match, handshake, peer upsert, send, file-send, and inbound task events.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- Updated OpenClaw plugin SDK metadata and type imports to the 2026.5.2 plugin entrypoint conventions.
|
|
19
|
+
- Reworked `CONFIG.md` and `README.md` installation/configuration guidance around OpenClaw plugin discovery.
|
|
20
|
+
- Changed encrypted handshake temporary inbound tokens to fixed 48-character lowercase hex values and documented that they are generated locally with a TTL instead of using long-lived `security.token`.
|
|
21
|
+
- Refactored `a2a_match_request` to reuse the same match/handshake implementation as the new `a2a.match` gateway method.
|
|
22
|
+
- Made path tests use platform-native separators on Windows and POSIX.
|
|
23
|
+
- Updated the npm override for transitive `axios` from `1.15.0` to `1.16.0` to address current npm audit reports without downgrading the tested `openclaw@2026.5.2` dependency.
|
|
24
|
+
|
|
25
|
+
## [1.2.4] - 2026-04-14
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
- Added local long-term identity storage (`client_id + public_key`) for Hub registration and encrypted handshake flows.
|
|
29
|
+
- Added encrypted handshake payload generation, decryption, and temporary inbound token issuance for match-based peer connection bootstrap.
|
|
30
|
+
- Added Hub presence updates on startup and shutdown.
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
- Switched Hub registration from `address + token` to `client_id + public_key`.
|
|
34
|
+
- Switched Hub matchmaking from legacy token exchange to encrypted handshake message exchange.
|
|
35
|
+
- Updated `a2a_match_request` to create a match, send an encrypted offer, wait for an encrypted answer, and return temporary peer connection details.
|
|
36
|
+
- Updated provider-side pending match polling to consume handshake messages and answer them automatically.
|
|
37
|
+
|
|
38
|
+
## [1.2.3] - 2026-04-07
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
- Updated the default Hub server URL to `https://www.clawcrony.com` in runtime defaults and plugin default config.
|
|
42
|
+
- Updated `README.md` to document the new default Hub domain.
|
|
43
|
+
|
|
44
|
+
## [1.2.2] - 2026-04-06
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
- Added the missing `AgentSkillConfig` type import in `index.ts` so the npm package build succeeds after syncing the new skill catalog changes.
|
|
48
|
+
|
|
49
|
+
## [1.2.1] - 2026-04-06
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
- Expanded the Hub section in `README.md` to describe the current Hub dashboard visibility after Agent registration and matchmaking.
|
|
53
|
+
- Pinned `dependencies` and `devDependencies` in `package.json` to the exact versions currently resolved in `package-lock.json`.
|
|
54
|
+
|
|
55
|
+
## [1.2.0] - 2026-04-06
|
|
56
|
+
|
|
57
|
+
### Added
|
|
58
|
+
- Provider-side Hub pending match polling that automatically discovers pending matches assigned to the current agent.
|
|
59
|
+
- Automatic provider token submission and match completion after both sides finish token exchange.
|
|
60
|
+
- Preset skill catalog and lightweight skill normalization for `agentCard.skills`, while still allowing custom user-defined skills.
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
- Hub match response parsing now supports caller role, request id, token submission state, and completion readiness fields.
|
|
64
|
+
- `a2a_match_request` output now uses clearer token wording aligned with the Hub response semantics.
|
|
65
|
+
|
|
66
|
+
## [1.1.0] - 2026-03-26
|
|
67
|
+
|
|
68
|
+
### Changed
|
|
69
|
+
- `registration.password` is now optional. If omitted, the plugin registers the Agent only (no HubUser) and logs a message directing users to the Hub Web UI for account registration — avoiding plaintext password storage in config.
|
|
70
|
+
|
|
71
|
+
## [1.0.4] - 2026-03-26
|
|
72
|
+
|
|
73
|
+
### Fixed
|
|
74
|
+
- Fix missing `password` field in `parseConfig` registration object
|
|
75
|
+
|
|
76
|
+
## [1.0.3] - 2026-03-26
|
|
77
|
+
|
|
78
|
+
### Added
|
|
79
|
+
- Auto-register hub user for web dashboard login on startup (if `registration.password` is configured)
|
|
80
|
+
- New `registration.password` config field for web dashboard authentication
|
|
81
|
+
|
|
82
|
+
### Changed
|
|
83
|
+
- Hub registration now also calls `POST /api/hub-users/register` to align with openclaw-hub web auth
|
|
84
|
+
|
|
85
|
+
## [1.0.2] - 2026-03-25
|
|
86
|
+
|
|
87
|
+
### Changed
|
|
88
|
+
- Replace all a2a-gateway references with claw-crony
|
|
89
|
+
|
|
90
|
+
## [1.0.1] - 2026-03-25
|
|
91
|
+
|
|
92
|
+
### Changed
|
|
93
|
+
- Updated README.md and README_CN.md with npm install instructions
|
|
94
|
+
- Added npm package support (@clawcrony/claw-crony)
|
|
95
|
+
|
|
96
|
+
## [1.0.0] - 2026-03-24
|
|
97
|
+
|
|
98
|
+
### Added
|
|
99
|
+
- Initial release of Claw Crony A2A Gateway
|
|
100
|
+
- A2A Protocol v0.3.0 support (JSON-RPC / REST / gRPC)
|
|
101
|
+
- Hub matchmaking with token exchange
|
|
102
|
+
- Smart routing by message patterns, tags, or peer skills
|
|
103
|
+
- Bearer Token authentication with multi-token rotation
|
|
104
|
+
- Health checks with exponential backoff and circuit breaker
|
|
105
|
+
- File transfer with URI / base64 / MIME whitelist and SSRF protection
|
|
106
|
+
- JSONL audit logs and Telemetry metrics endpoint
|
|
107
|
+
- Based on [win4r/openclaw-a2a-gateway](https://github.com/win4r/openclaw-a2a-gateway)
|
package/CONFIG.md
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
# Claw Crony Configuration Guide
|
|
2
|
+
|
|
3
|
+
This document describes the current OpenClaw-facing configuration for `claw-crony`.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- OpenClaw 2026.5.2 or newer
|
|
8
|
+
- Node.js 22 or newer
|
|
9
|
+
- Network reachability between A2A peers when using direct peer calls
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
Use OpenClaw's plugin installer so the manifest and install registry are updated
|
|
14
|
+
correctly.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
openclaw plugins install git:github.com/ccccl8/claw-crony.git
|
|
18
|
+
openclaw plugins inspect claw-crony
|
|
19
|
+
openclaw plugins inspect claw-crony --runtime
|
|
20
|
+
openclaw gateway restart
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For local development from a checkout:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cd /absolute/path/to/claw-crony
|
|
27
|
+
npm install
|
|
28
|
+
openclaw plugins install -l /absolute/path/to/claw-crony
|
|
29
|
+
openclaw plugins inspect claw-crony --runtime
|
|
30
|
+
openclaw gateway restart
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Pass the plugin root directory, the directory that contains
|
|
34
|
+
`openclaw.plugin.json` and `package.json`. Do not pass the parent `plugins/`
|
|
35
|
+
directory.
|
|
36
|
+
|
|
37
|
+
## What OpenClaw Handles Automatically
|
|
38
|
+
|
|
39
|
+
After installation through `openclaw plugins install`, OpenClaw can discover
|
|
40
|
+
these items from `openclaw.plugin.json` and `package.json`:
|
|
41
|
+
|
|
42
|
+
| Item | Source | User action |
|
|
43
|
+
|------|--------|-------------|
|
|
44
|
+
| Plugin id `claw-crony` | `openclaw.plugin.json` | None |
|
|
45
|
+
| Plugin version `1.3.0` | `openclaw.plugin.json` / `package.json` | None |
|
|
46
|
+
| Startup activation | `activation.onStartup` | None |
|
|
47
|
+
| Agent tools | `contracts.tools` | None |
|
|
48
|
+
| Tools `a2a_send_file`, `a2a_match_request` | Runtime registration + manifest contract | None |
|
|
49
|
+
| OpenClaw compatibility | `package.json#openclaw.compat` | None |
|
|
50
|
+
| Plugin entrypoint | `package.json#openclaw.extensions` | None |
|
|
51
|
+
| Install registry metadata | OpenClaw plugin installer | None |
|
|
52
|
+
| `plugins.entries.claw-crony.enabled` | OpenClaw plugin installer/enable flow | Usually none |
|
|
53
|
+
| `plugins.allow` update | OpenClaw plugin installer, when allowlist is configured | Usually none |
|
|
54
|
+
|
|
55
|
+
The plugin also has runtime defaults, so an empty
|
|
56
|
+
`plugins.entries.claw-crony.config` is valid. You only need to add values that
|
|
57
|
+
are environment-specific, especially public/reachable addresses and security
|
|
58
|
+
tokens.
|
|
59
|
+
|
|
60
|
+
## Minimal User Configuration
|
|
61
|
+
|
|
62
|
+
For a real multi-machine setup, set at least:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
openclaw config set plugins.entries.claw-crony.config.agentCard.name "My Agent"
|
|
66
|
+
openclaw config set plugins.entries.claw-crony.config.agentCard.url "http://<reachable-host>:18800/a2a/jsonrpc"
|
|
67
|
+
openclaw config set plugins.entries.claw-crony.config.routing.defaultAgentId "main"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`agentCard.url` should use an address reachable by peer machines and the Hub:
|
|
71
|
+
Tailscale IP, LAN IP, public DNS name, or reverse-proxy URL. If omitted, the
|
|
72
|
+
plugin can fall back to localhost, which is only useful for local testing.
|
|
73
|
+
|
|
74
|
+
If the A2A server is reachable outside the machine, enable bearer auth:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
TOKEN=$(openssl rand -hex 24)
|
|
78
|
+
openclaw config set plugins.entries.claw-crony.config.security.inboundAuth "bearer"
|
|
79
|
+
openclaw config set plugins.entries.claw-crony.config.security.token "$TOKEN"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
For zero-downtime token rotation, use `security.tokens` alongside or instead of
|
|
83
|
+
`security.token`:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
openclaw config set plugins.entries.claw-crony.config.security.tokens '["old-token","new-token"]'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Hub Configuration
|
|
90
|
+
|
|
91
|
+
Hub integration is enabled by default and points to `https://www.clawcrony.com`.
|
|
92
|
+
Normally you do not need to set these values.
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
openclaw config set plugins.entries.claw-crony.config.hub.url "https://www.clawcrony.com"
|
|
96
|
+
openclaw config set plugins.entries.claw-crony.config.hub.enabled true
|
|
97
|
+
openclaw config set plugins.entries.claw-crony.config.hub.registrationEnabled true
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Optional dashboard registration fields:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
openclaw config set plugins.entries.claw-crony.config.registration.username "your-username"
|
|
104
|
+
openclaw config set plugins.entries.claw-crony.config.registration.email "your@email.com"
|
|
105
|
+
openclaw config set plugins.entries.claw-crony.config.registration.password "your-password"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`registration.password` is only needed if you want the plugin to create the Hub
|
|
109
|
+
dashboard login for you. If omitted, the Agent still registers with the Hub and
|
|
110
|
+
you can create the dashboard account in the Hub UI.
|
|
111
|
+
|
|
112
|
+
`registration.clientId` is optional. If omitted, `claw-crony` generates a stable
|
|
113
|
+
local identity and stores it under the OpenClaw config directory. Set this only
|
|
114
|
+
when you intentionally need to pin the Hub client id:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
openclaw config set plugins.entries.claw-crony.config.registration.clientId "my-stable-client-id"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Direct Peer Configuration
|
|
121
|
+
|
|
122
|
+
Manual peers are only required for fixed direct routing. Hub matchmaking can
|
|
123
|
+
discover a provider and exchange temporary connection details without manually
|
|
124
|
+
pre-populating `peers`.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
openclaw config set plugins.entries.claw-crony.config.peers '[
|
|
128
|
+
{
|
|
129
|
+
"name": "Server-B",
|
|
130
|
+
"agentCardUrl": "http://100.10.10.2:18800/.well-known/agent-card.json",
|
|
131
|
+
"auth": { "type": "bearer", "token": "<B_TOKEN>" }
|
|
132
|
+
}
|
|
133
|
+
]'
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
The plugin also serves `/.well-known/agent.json` as a compatibility alias, but
|
|
137
|
+
`/.well-known/agent-card.json` is the preferred SDK discovery path.
|
|
138
|
+
|
|
139
|
+
## Routing Rules
|
|
140
|
+
|
|
141
|
+
`routing.defaultAgentId` selects the local OpenClaw agent that should receive
|
|
142
|
+
inbound A2A messages. `routing.rules` can choose an outbound peer for
|
|
143
|
+
`a2a.send` when the caller does not provide an explicit peer.
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
openclaw config set plugins.entries.claw-crony.config.routing.defaultAgentId "main"
|
|
147
|
+
openclaw config set plugins.entries.claw-crony.config.routing.rules '[
|
|
148
|
+
{
|
|
149
|
+
"name": "code-review-to-server-b",
|
|
150
|
+
"match": { "skills": ["code_review"], "pattern": "review|diff|pull request" },
|
|
151
|
+
"target": { "peer": "Server-B", "agentId": "main" },
|
|
152
|
+
"priority": 10
|
|
153
|
+
}
|
|
154
|
+
]'
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Optional OpenClaw Hook Fallback
|
|
158
|
+
|
|
159
|
+
The plugin now registers native OpenClaw lifecycle hooks:
|
|
160
|
+
|
|
161
|
+
- `gateway_start`
|
|
162
|
+
- `gateway_stop`
|
|
163
|
+
|
|
164
|
+
No user configuration is required for these lifecycle hooks.
|
|
165
|
+
|
|
166
|
+
There is also a legacy `/hooks/wake` fallback used only when normal Gateway RPC
|
|
167
|
+
dispatch fails. To allow that fallback, configure OpenClaw's global hook token,
|
|
168
|
+
not the plugin config:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
openclaw config set hooks.token "<shared-hook-token>"
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Leave `hooks.token` unset if you do not use the legacy wake fallback.
|
|
175
|
+
|
|
176
|
+
## Configuration Reference
|
|
177
|
+
|
|
178
|
+
All plugin-owned values live under:
|
|
179
|
+
|
|
180
|
+
```text
|
|
181
|
+
plugins.entries.claw-crony.config
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
| Config path | Type | Default | Notes |
|
|
185
|
+
|-------------|------|---------|-------|
|
|
186
|
+
| `agentCard.name` | string | `OpenClaw A2A Gateway` | Display name published in the Agent Card and Hub registration. |
|
|
187
|
+
| `agentCard.description` | string | `A2A bridge for OpenClaw agents` | Human-readable Agent description. |
|
|
188
|
+
| `agentCard.url` | string | derived from server config | Public JSON-RPC endpoint. Set this for remote peers and Hub matchmaking. |
|
|
189
|
+
| `agentCard.skills` | array | `[{id:"chat",name:"chat",description:"Chat bridge"}]` | Skills sent to the Hub and exposed in the Agent Card. |
|
|
190
|
+
| `hub.url` | string | `https://www.clawcrony.com` | Hub API base URL. |
|
|
191
|
+
| `hub.enabled` | boolean | `true` | Enables Hub presence, matchmaking, and pending-match polling. |
|
|
192
|
+
| `hub.registrationEnabled` | boolean | `true` | Registers or confirms this Agent with the Hub on startup. |
|
|
193
|
+
| `registration.username` | string | agent name | Optional Hub dashboard username. |
|
|
194
|
+
| `registration.email` | string | empty | Optional Hub dashboard email. |
|
|
195
|
+
| `registration.password` | string | empty | Optional Hub dashboard password. Sensitive. |
|
|
196
|
+
| `registration.clientId` | string | generated and persisted | Optional stable Hub client id override. |
|
|
197
|
+
| `server.host` | string | `0.0.0.0` | A2A HTTP/gRPC bind host. |
|
|
198
|
+
| `server.port` | number | `18800` | A2A HTTP port. gRPC uses `server.port + 1`. |
|
|
199
|
+
| `storage.tasksDir` | string | `~/.openclaw/a2a-tasks` | Durable A2A task store. Relative paths are resolved by OpenClaw/plugin path handling. |
|
|
200
|
+
| `storage.taskTtlHours` | number | `72` | Terminal task retention period. Minimum `1`. |
|
|
201
|
+
| `storage.cleanupIntervalMinutes` | number | `60` | Task cleanup interval. Minimum `1`. |
|
|
202
|
+
| `peers` | array | `[]` | Static direct peer list. Optional when using Hub matchmaking. |
|
|
203
|
+
| `peers[].name` | string | required | Peer display/routing name. |
|
|
204
|
+
| `peers[].agentCardUrl` | string | required | Peer Agent Card URL. Prefer `/.well-known/agent-card.json`. |
|
|
205
|
+
| `peers[].auth.type` | string | optional | `bearer` or `apiKey`. |
|
|
206
|
+
| `peers[].auth.token` | string | optional | Token sent to the peer. Sensitive. |
|
|
207
|
+
| `security.inboundAuth` | string | `none` | `none` or `bearer`. Use `bearer` for non-local exposure. |
|
|
208
|
+
| `security.token` | string | empty | Single inbound bearer token. Sensitive. |
|
|
209
|
+
| `security.tokens` | string[] | `[]` | Multiple inbound tokens for rotation. Sensitive. |
|
|
210
|
+
| `security.allowedMimeTypes` | string[] | image, PDF, text, JSON, audio, video | MIME allowlist for inbound and outbound file parts. Supports wildcards such as `image/*`. |
|
|
211
|
+
| `security.maxFileSizeBytes` | number | `52428800` | Max URI-based outbound file size, 50 MB by default. |
|
|
212
|
+
| `security.maxInlineFileSizeBytes` | number | `10485760` | Max inline base64 file size, 10 MB by default. |
|
|
213
|
+
| `security.fileUriAllowlist` | string[] | `[]` | Optional hostname allowlist for outbound file URIs. Empty means public hosts are allowed after SSRF checks. |
|
|
214
|
+
| `routing.defaultAgentId` | string | `default` | Local OpenClaw agent id for inbound A2A dispatch. |
|
|
215
|
+
| `routing.rules` | array | `[]` | Optional outbound routing rules for `a2a.send`. |
|
|
216
|
+
| `limits.maxConcurrentTasks` | number | `4` | Max concurrently running inbound tasks. |
|
|
217
|
+
| `limits.maxQueuedTasks` | number | `100` | Max queued inbound tasks before rejection. |
|
|
218
|
+
| `observability.structuredLogs` | boolean | `true` | Emits structured JSON-like log entries. |
|
|
219
|
+
| `observability.exposeMetricsEndpoint` | boolean | `true` | Exposes metrics over HTTP. |
|
|
220
|
+
| `observability.metricsPath` | string | `/a2a/metrics` | Metrics endpoint path. |
|
|
221
|
+
| `observability.metricsAuth` | string | `none` | `none` or `bearer`; bearer reuses `security.token`/`security.tokens`. |
|
|
222
|
+
| `observability.auditLogPath` | string | `~/.openclaw/a2a-audit.jsonl` | JSONL audit log path. |
|
|
223
|
+
| `observability.historyEnabled` | boolean | `true` | Writes operator-facing JSONL request history for match, handshake, peer, send, and file-send events. |
|
|
224
|
+
| `observability.historyLogPath` | string | `~/.openclaw/a2a-history.jsonl` | JSONL request history path. |
|
|
225
|
+
| `observability.historyIncludeEncryptedPayloads` | boolean | `false` | Include encrypted handshake payload fields in request history. Tokens/secrets remain redacted. |
|
|
226
|
+
| `timeouts.agentResponseTimeoutMs` | number | `300000` | Max wait for an OpenClaw Agent response in blocking mode. |
|
|
227
|
+
| `resilience.healthCheck.enabled` | boolean | `true` | Enables peer health checks for static peers. |
|
|
228
|
+
| `resilience.healthCheck.intervalMs` | number | `30000` | Peer health check interval. |
|
|
229
|
+
| `resilience.healthCheck.timeoutMs` | number | `5000` | Peer health check timeout. |
|
|
230
|
+
| `resilience.retry.maxRetries` | number | `3` | Retry attempts for retryable outbound peer errors. |
|
|
231
|
+
| `resilience.retry.baseDelayMs` | number | `1000` | Initial retry delay. |
|
|
232
|
+
| `resilience.retry.maxDelayMs` | number | `10000` | Maximum retry delay. |
|
|
233
|
+
| `resilience.circuitBreaker.failureThreshold` | number | `5` | Consecutive failures before opening a peer circuit. |
|
|
234
|
+
| `resilience.circuitBreaker.resetTimeoutMs` | number | `30000` | Time before an open peer circuit enters half-open mode. |
|
|
235
|
+
|
|
236
|
+
## Full Example
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
TOKEN=$(openssl rand -hex 24)
|
|
240
|
+
|
|
241
|
+
openclaw plugins install git:github.com/ccccl8/claw-crony.git
|
|
242
|
+
|
|
243
|
+
openclaw config set plugins.entries.claw-crony.config.agentCard.name "Server-A"
|
|
244
|
+
openclaw config set plugins.entries.claw-crony.config.agentCard.description "Server A OpenClaw A2A agent"
|
|
245
|
+
openclaw config set plugins.entries.claw-crony.config.agentCard.url "http://100.10.10.1:18800/a2a/jsonrpc"
|
|
246
|
+
openclaw config set plugins.entries.claw-crony.config.agentCard.skills '["chat","reasoning","code_review"]'
|
|
247
|
+
openclaw config set plugins.entries.claw-crony.config.routing.defaultAgentId "main"
|
|
248
|
+
openclaw config set plugins.entries.claw-crony.config.security.inboundAuth "bearer"
|
|
249
|
+
openclaw config set plugins.entries.claw-crony.config.security.token "$TOKEN"
|
|
250
|
+
|
|
251
|
+
openclaw gateway restart
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Verify
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
openclaw plugins inspect claw-crony
|
|
258
|
+
openclaw plugins inspect claw-crony --runtime
|
|
259
|
+
curl -s http://localhost:18800/.well-known/agent-card.json
|
|
260
|
+
curl -s http://localhost:18800/a2a/metrics
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
If `observability.metricsAuth` is `bearer`, call metrics with the inbound token:
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
curl -H "Authorization: Bearer $TOKEN" http://localhost:18800/a2a/metrics
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Gateway Methods and Scripts
|
|
270
|
+
|
|
271
|
+
OpenClaw can call claw-crony directly through gateway methods. The plugin
|
|
272
|
+
registers:
|
|
273
|
+
|
|
274
|
+
| Method | Purpose |
|
|
275
|
+
|--------|---------|
|
|
276
|
+
| `a2a.match` | Creates a Hub match and performs the encrypted handshake. Same core logic as `a2a_match_request`. |
|
|
277
|
+
| `a2a.peers` | Lists current configured and runtime-discovered peers with tokens redacted. |
|
|
278
|
+
| `a2a.history` | Reads recent request history with optional filters: `count`, `type`, `status`, `direction`, `matchId`, `peer`. |
|
|
279
|
+
| `a2a.send` | Sends a message to a direct or Hub-discovered peer. |
|
|
280
|
+
| `a2a.audit` | Reads the lower-level audit log. |
|
|
281
|
+
| `a2a.metrics` | Returns telemetry metrics. |
|
|
282
|
+
|
|
283
|
+
Convenience scripts are available in `scripts/`:
|
|
284
|
+
|
|
285
|
+
```powershell
|
|
286
|
+
.\scripts\a2a-match.ps1 -Skills chat,code_review -Description "Need code review"
|
|
287
|
+
.\scripts\a2a-peers.ps1
|
|
288
|
+
.\scripts\a2a-send.ps1 -Peer "Provider Name" -Text "hello" -AgentId "main"
|
|
289
|
+
.\scripts\a2a-history.ps1 -Count 20 -MatchId 123
|
|
290
|
+
.\scripts\a2a-diagnose.ps1
|
|
291
|
+
.\scripts\a2a-update.ps1
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
./scripts/a2a-match.sh chat,code_review "Need code review"
|
|
296
|
+
./scripts/a2a-peers.sh
|
|
297
|
+
./scripts/a2a-send.sh "Provider Name" "hello" main
|
|
298
|
+
./scripts/a2a-history.sh 20 handshake.answer_received 123
|
|
299
|
+
./scripts/a2a-diagnose.sh
|
|
300
|
+
./scripts/a2a-update.sh
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
History entries redact `token`, `secret`, `password`, `authorization`, and
|
|
304
|
+
`ciphertext` fields by default. Leave
|
|
305
|
+
`observability.historyIncludeEncryptedPayloads=false` unless you are debugging a
|
|
306
|
+
Hub handshake issue and understand that encrypted payloads may still be
|
|
307
|
+
sensitive metadata.
|
|
308
|
+
|
|
309
|
+
## Troubleshooting
|
|
310
|
+
|
|
311
|
+
### Plugin is not listed
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
openclaw plugins registry --refresh
|
|
315
|
+
openclaw plugins list
|
|
316
|
+
openclaw plugins inspect claw-crony
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
If you installed from a local checkout, confirm that the path points to the
|
|
320
|
+
plugin root and that `npm install` has already been run.
|
|
321
|
+
|
|
322
|
+
### Agent Card is not reachable
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
openclaw gateway restart
|
|
326
|
+
curl -s http://localhost:18800/.well-known/agent-card.json
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
If remote peers cannot reach it, set `agentCard.url` to a reachable address and
|
|
330
|
+
check firewall/security-group rules for `server.port`.
|
|
331
|
+
|
|
332
|
+
### "Request accepted (no agent dispatch available)"
|
|
333
|
+
|
|
334
|
+
The A2A gateway accepted the task but OpenClaw did not return a final Agent
|
|
335
|
+
response. Check that the target OpenClaw Agent/provider is configured and that
|
|
336
|
+
the task did not exceed `timeouts.agentResponseTimeoutMs`.
|
|
337
|
+
|
|
338
|
+
### Peer auth failed
|
|
339
|
+
|
|
340
|
+
Make sure the sender's peer token matches the receiver's
|
|
341
|
+
`security.token` or one value in `security.tokens`.
|
package/README.md
CHANGED
|
@@ -12,9 +12,10 @@ OpenClaw A2A v0.3.0 Gateway - Auto-discovery and secure communication between Op
|
|
|
12
12
|
- **Smart Routing** - Auto-select targets by message patterns, tags, or peer skills
|
|
13
13
|
- **Secure Auth** - Bearer Token + zero-downtime multi-token rotation
|
|
14
14
|
- **Private Hub Identity** - Register with `client_id + public_key` instead of publishing long-lived connection secrets
|
|
15
|
+
- **Native OpenClaw Lifecycle Hooks** - Uses `gateway_start` / `gateway_stop` for Hub registration and presence updates
|
|
15
16
|
- **Resilience** - Health checks + exponential backoff + circuit breaker
|
|
16
17
|
- **File Transfer** - URI / base64 / MIME whitelist + SSRF protection
|
|
17
|
-
- **Observability** - JSONL audit logs + Telemetry metrics endpoint
|
|
18
|
+
- **Observability** - JSONL audit logs + request history + Telemetry metrics endpoint
|
|
18
19
|
|
|
19
20
|
## Hub Server
|
|
20
21
|
|
|
@@ -24,47 +25,134 @@ After installation, the plugin auto-registers with the Hub (requires `registrati
|
|
|
24
25
|
|
|
25
26
|
Once registered, use the `a2a_match_request` tool to send a matchmaking request. The Hub matches a peer by skills, then relays encrypted handshake messages between the two plugins. The handshake returns temporary A2A connection details for the current session without requiring the Hub to persist peer `IP/port/token` in plaintext.
|
|
26
27
|
|
|
28
|
+
During handshake, the OpenClaw-loaded `claw-crony` plugin calls
|
|
29
|
+
`issueEphemeralInboundToken(...)` locally to create a temporary inbound bearer
|
|
30
|
+
token. This token is added to the local runtime `validTokens` set and expires
|
|
31
|
+
after its TTL. It is not the long-lived `security.token`, and it is not written
|
|
32
|
+
back to OpenClaw config.
|
|
33
|
+
|
|
27
34
|
After the user signs in to the Hub web dashboard, they can currently see:
|
|
28
35
|
|
|
29
|
-
- Their own Agent profile
|
|
36
|
+
- Their own Agent profile and registered metadata
|
|
30
37
|
- A match timeline for requests created by this Agent
|
|
31
38
|
- Per-request request summary, required skills, and current status
|
|
32
|
-
- Matched result details
|
|
39
|
+
- Matched result details for the linked provider and current result state
|
|
40
|
+
|
|
41
|
+
The dashboard is still being migrated to the new encrypted-handshake model. Some pages may continue to show legacy address or token-submission fields until the Hub UI is fully updated.
|
|
33
42
|
|
|
34
43
|
A2A service port: **18800** (default)
|
|
35
44
|
|
|
36
45
|
## Installation
|
|
37
46
|
|
|
38
|
-
|
|
47
|
+
Compatibility note: the current release has only been adapted and tested against
|
|
48
|
+
OpenClaw 2026.5.2. Older OpenClaw versions and future OpenClaw versions may not
|
|
49
|
+
be compatible without additional changes.
|
|
50
|
+
|
|
51
|
+
Use OpenClaw's plugin installer so the manifest and install registry are updated
|
|
52
|
+
correctly. This lets OpenClaw discover the plugin id, startup activation, tool
|
|
53
|
+
contracts, runtime entrypoint, and compatibility metadata.
|
|
39
54
|
|
|
40
55
|
```bash
|
|
41
|
-
|
|
56
|
+
openclaw plugins install git:github.com/ccccl8/claw-crony.git
|
|
57
|
+
openclaw plugins inspect claw-crony
|
|
58
|
+
openclaw plugins inspect claw-crony --runtime
|
|
59
|
+
openclaw gateway restart
|
|
42
60
|
```
|
|
43
61
|
|
|
44
|
-
|
|
62
|
+
For local development from a checkout:
|
|
45
63
|
|
|
46
64
|
```bash
|
|
47
|
-
|
|
48
|
-
cd claw-crony
|
|
65
|
+
cd /absolute/path/to/claw-crony
|
|
49
66
|
npm install
|
|
50
|
-
openclaw plugins install
|
|
67
|
+
openclaw plugins install -l /absolute/path/to/claw-crony
|
|
68
|
+
openclaw plugins inspect claw-crony --runtime
|
|
51
69
|
openclaw gateway restart
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Pass the plugin root directory, the directory that contains
|
|
73
|
+
`openclaw.plugin.json` and `package.json`.
|
|
74
|
+
|
|
75
|
+
## OpenClaw Discovery and Hooks
|
|
76
|
+
|
|
77
|
+
After installation, OpenClaw reads `openclaw.plugin.json` and `package.json`
|
|
78
|
+
before loading plugin runtime code. The current plugin declares:
|
|
79
|
+
|
|
80
|
+
- Plugin id: `claw-crony`
|
|
81
|
+
- Startup activation: `activation.onStartup`
|
|
82
|
+
- Tool contracts: `a2a_send_file`, `a2a_match_request`
|
|
83
|
+
- OpenClaw compatibility: adapted and tested with `2026.5.2`; other versions are not guaranteed
|
|
84
|
+
- Runtime entrypoint: `./index.ts`
|
|
85
|
+
|
|
86
|
+
At runtime, `claw-crony` registers native OpenClaw lifecycle hooks:
|
|
87
|
+
|
|
88
|
+
- `gateway_start`: starts Hub registration/presence lifecycle
|
|
89
|
+
- `gateway_stop`: marks Hub presence offline during Gateway shutdown
|
|
52
90
|
|
|
53
|
-
|
|
54
|
-
|
|
91
|
+
No user configuration is required for these lifecycle hooks. The plugin also
|
|
92
|
+
keeps its existing background service registration for the A2A HTTP/gRPC
|
|
93
|
+
servers.
|
|
94
|
+
|
|
95
|
+
There is one optional legacy fallback: if normal Gateway RPC dispatch fails,
|
|
96
|
+
`claw-crony` can try OpenClaw's `/hooks/wake` endpoint. To enable that fallback,
|
|
97
|
+
set OpenClaw's global hook token:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
openclaw config set hooks.token "<shared-hook-token>"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Leave `hooks.token` unset if you do not use the legacy wake fallback.
|
|
104
|
+
|
|
105
|
+
## Minimal Configuration
|
|
106
|
+
|
|
107
|
+
The plugin has runtime defaults, so an empty
|
|
108
|
+
`plugins.entries.claw-crony.config` is valid. For a real multi-machine setup,
|
|
109
|
+
set the public/reachable Agent Card URL and the target local OpenClaw agent id:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
openclaw config set plugins.entries.claw-crony.config.agentCard.name "My Agent"
|
|
113
|
+
openclaw config set plugins.entries.claw-crony.config.agentCard.url "http://<reachable-host>:18800/a2a/jsonrpc"
|
|
114
|
+
openclaw config set plugins.entries.claw-crony.config.routing.defaultAgentId "main"
|
|
55
115
|
```
|
|
56
116
|
|
|
57
|
-
|
|
117
|
+
If the A2A server is reachable outside the machine, enable bearer auth:
|
|
58
118
|
|
|
59
119
|
```bash
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"auth": { "type": "bearer", "token": "<peerToken>" }
|
|
64
|
-
}]'
|
|
120
|
+
TOKEN=$(openssl rand -hex 24)
|
|
121
|
+
openclaw config set plugins.entries.claw-crony.config.security.inboundAuth "bearer"
|
|
122
|
+
openclaw config set plugins.entries.claw-crony.config.security.token "$TOKEN"
|
|
65
123
|
openclaw gateway restart
|
|
66
124
|
```
|
|
67
125
|
|
|
126
|
+
Useful optional settings:
|
|
127
|
+
|
|
128
|
+
- `agentCard.skills`: skills sent to the Hub and exposed in the Agent Card
|
|
129
|
+
- `security.tokens`: multiple inbound tokens for zero-downtime rotation
|
|
130
|
+
- `observability.metricsAuth`: set to `bearer` to protect `/a2a/metrics`
|
|
131
|
+
- `observability.historyEnabled`: keep request history for match, handshake, peer, send, and file-send events
|
|
132
|
+
- `hub.enabled`: set to `false` to disable Hub integration
|
|
133
|
+
|
|
134
|
+
For the full parameter reference, see [CONFIG.md](CONFIG.md).
|
|
135
|
+
|
|
136
|
+
## Adding a Direct Peer
|
|
137
|
+
|
|
138
|
+
Manual peers are only required for fixed direct routing. Hub matchmaking can
|
|
139
|
+
discover a provider and exchange temporary connection details without manually
|
|
140
|
+
pre-populating `peers`.
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
openclaw config set plugins.entries.claw-crony.config.peers '[
|
|
144
|
+
{
|
|
145
|
+
"name": "Peer Name",
|
|
146
|
+
"agentCardUrl": "http://<peerIP>:18800/.well-known/agent-card.json",
|
|
147
|
+
"auth": { "type": "bearer", "token": "<peerToken>" }
|
|
148
|
+
}
|
|
149
|
+
]'
|
|
150
|
+
openclaw gateway restart
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
`/.well-known/agent-card.json` is the preferred SDK discovery path. The plugin
|
|
154
|
+
also serves `/.well-known/agent.json` as a compatibility alias.
|
|
155
|
+
|
|
68
156
|
## Hub Matchmaking (a2a_match_request)
|
|
69
157
|
|
|
70
158
|
Send a matchmaking request to the Hub, which automatically finds registered Agents with the required skills:
|
|
@@ -77,13 +165,54 @@ Send a matchmaking request to the Hub, which automatically finds registered Agen
|
|
|
77
165
|
# Both sides then communicate directly over A2A without the Hub relaying task payloads
|
|
78
166
|
```
|
|
79
167
|
|
|
168
|
+
The temporary inbound token exchanged here is generated locally by
|
|
169
|
+
`issueEphemeralInboundToken(...)` when the handshake message is created. It has
|
|
170
|
+
a TTL and is kept only in the running plugin process. Do not use the long-lived
|
|
171
|
+
`security.token` as the handshake token.
|
|
172
|
+
|
|
80
173
|
For detailed configuration steps, see [CONFIG.md](CONFIG.md).
|
|
81
174
|
|
|
175
|
+
## Gateway Methods and Helper Scripts
|
|
176
|
+
|
|
177
|
+
OpenClaw can call claw-crony without asking the agent to write ad-hoc scripts:
|
|
178
|
+
|
|
179
|
+
| Method | Description |
|
|
180
|
+
|--------|-------------|
|
|
181
|
+
| `a2a.match` | Creates a Hub match and performs the encrypted handshake. |
|
|
182
|
+
| `a2a.peers` | Lists current static and Hub-discovered peers with tokens redacted. |
|
|
183
|
+
| `a2a.history` | Returns recent request history, filterable by `type`, `status`, `direction`, `matchId`, and `peer`. |
|
|
184
|
+
| `a2a.send` | Sends an A2A message to a peer. |
|
|
185
|
+
| `a2a.audit` | Returns lower-level audit entries. |
|
|
186
|
+
| `a2a.metrics` | Returns telemetry metrics. |
|
|
187
|
+
|
|
188
|
+
Scripts in `scripts/` wrap the common gateway calls:
|
|
189
|
+
|
|
190
|
+
```powershell
|
|
191
|
+
.\scripts\a2a-match.ps1 -Skills chat,code_review -Description "Need code review"
|
|
192
|
+
.\scripts\a2a-peers.ps1
|
|
193
|
+
.\scripts\a2a-send.ps1 -Peer "Provider Name" -Text "hello" -AgentId "main"
|
|
194
|
+
.\scripts\a2a-history.ps1 -Count 20 -MatchId 123
|
|
195
|
+
.\scripts\a2a-diagnose.ps1
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
./scripts/a2a-match.sh chat,code_review "Need code review"
|
|
200
|
+
./scripts/a2a-peers.sh
|
|
201
|
+
./scripts/a2a-send.sh "Provider Name" "hello" main
|
|
202
|
+
./scripts/a2a-history.sh 20 handshake.answer_received 123
|
|
203
|
+
./scripts/a2a-diagnose.sh
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Request history is written to `~/.openclaw/a2a-history.jsonl` by default.
|
|
207
|
+
Tokens, passwords, authorization headers, secrets, and handshake ciphertext are
|
|
208
|
+
redacted unless explicitly configured otherwise.
|
|
209
|
+
|
|
82
210
|
## Endpoints
|
|
83
211
|
|
|
84
212
|
| Endpoint | Method | Description |
|
|
85
213
|
|----------|--------|-------------|
|
|
86
|
-
| `/.well-known/agent-card.json` | GET | Agent Card (discovery) |
|
|
214
|
+
| `/.well-known/agent-card.json` | GET | Agent Card (preferred SDK discovery) |
|
|
215
|
+
| `/.well-known/agent.json` | GET | Agent Card compatibility alias |
|
|
87
216
|
| `/a2a/jsonrpc` | POST | A2A JSON-RPC |
|
|
88
217
|
| `/a2a/rest` | POST | A2A REST transport |
|
|
89
218
|
| `/a2a/metrics` | GET | Telemetry snapshot (when enabled) |
|